devise
devise copied to clipboard
DisabledSessionError when using authenticate_user! api only
Pre Check
- Create a new Rails 7 app
rails new test_app --api
- Add devise
- run
rails g devise:install
- run
rails g devise User
- POST to
/users
and see the error stated below
Environment
- Ruby 3.0.0
- Rails 7.0.0
- Devise 4.8.1
Current behavior
When using authenticate_user! on a controller on a rails API only app I am getting the following error:
ActionDispatch::Request::Session::DisabledSessionError (Your application has sessions disabled. To write to the session you must first configure a session store):
Expected behavior
It should throw fail or success on warden depending on if the user is signed in or not.
More context: Before Rails 7, the session passed to warden was a Hash. So even if the session was disabled, we were still able to write to the hash. Now, the session is an ActionDispatch::Session
object, which is not writable on Rails API only apps, because the ActionDispatch::Session is disabled.
I understand that Devise relies heavily on warden etc which rely on sessions, or a fake version of it at least. Thus, we've circumvented this by creating this concern/module that we have included in the relevant Devise-related controllers in our app:
module RackSessionFixController
extend ActiveSupport::Concern
class FakeRackSession < Hash
def enabled?
false
end
end
included do
before_action :set_fake_rack_session_for_devise
private
def set_fake_rack_session_for_devise
request.env['rack.session'] ||= FakeRackSession.new
end
end
end
if the devise maintainers like it, we (AKA me or my team) can integrate this into Devise itself (E.g. allowing that logic to happen when API-mode is enabled) and expand the testsuite accordingly.
@carlosantoniodasilva WDYT ?
@morenocarullo i use Rails.application.config.session_store :disabled
and have the same Problem can you provide your FakeRakeSession Example?
@arpu you need to drop that module I wrote in my earlier comment and include it in the SessionControllers. If @carlosantoniodasilva or other maintainer can suggest their acceptance, I can for sure make it included in devise
itself so that it's automatic.
reference rails change https://github.com/rails/rails/pull/42231
I understand that Devise relies heavily on warden etc which rely on sessions, or a fake version of it at least. Thus, we've circumvented this by creating this concern/module that we have included in the relevant Devise-related controllers in our app:
module RackSessionFixController extend ActiveSupport::Concern class FakeRackSession < Hash def enabled? false end end included do before_action :set_fake_rack_session_for_devise private def set_fake_rack_session_for_devise request.env['rack.session'] ||= FakeRackSession.new end end end
if the devise maintainers like it, we (AKA me or my team) can integrate this into Devise itself (E.g. allowing that logic to happen when API-mode is enabled) and expand the testsuite accordingly.
@carlosantoniodasilva WDYT ?
Thanks a lot for the help @morenocarullo.
I am using this resolution while the issue is not resolved
Any update on when this will be fixed?
@connortorrell you can use the solution posted here. I'm waiting for maintainers to say they'll accept the PR -- before it stays there forever
Did they accept the PR?
@NfoCipher I was waiting for an OK here to create the PR. BUT, since I got no answer ... I'll create the PR so that at least people can have a branch to point to, and will push to make it merged..
Thank you @morenocarullo, using your fix as well. +1 for getting an official fix merged
FYI, I am preparing a PR for this issue. To begin with, we'll have a fork with the fix applied which is slightly better than the module-drop-in there, but I really want to make it upstream into the official branch.
PR is here: https://github.com/heartcombo/devise/pull/5474
Feel free to use the referenced branch/fork while we wait for it to be merged.
This: https://github.com/waiting-for-dev/devise-jwt/issues/235#issuecomment-1116864740 also seems to work.
Hi, I am facing this error Minitest::UnexpectedError: ActionDispatch::Request::Session::DisabledSessionError: Your application has sessions disabled. To write to the session you must first configure a session store
in testing environment. I am trying to do a simple assertion like
test "should get index" do
sign_in users(:one)
get movies_url, as: :json
assert_response :success
end
but even having both workarounds (the one in application.rb and the other having RackSessionFix.rb) is not working.
Any ideas? Thanks.
As described in https://github.com/wardencommunity/warden/blob/master/lib/warden/proxy.rb#L167 need to pass store: false
to skip serializing into the session.
So adding
def sign_up(resource_name, resource)
sign_in(resource_name, resource, store: false)
end
in your controller inherited from Devise::RegistrationsController
should solve the problem
In case this helps someone, you'll also need to pass in store: false
for logging in.
This needs to be added to the controller inherited from Devise::SessionsController
def auth_options
super.merge({store: false})
end
Hi, any new about a fix ? Thx :)
This worked for me :
# application.rb
config.session_store :cookie_store, key: '_interslice_session'
config.middleware.use ActionDispatch::Cookies
config.middleware.use config.session_store, config.session_options
No news :), but thanks for putting it into my radar again, I'll try to take a better look at the problem and the proposed solution(s) here. Thanks.
Any reason this is still held up ?