heartcombo / devise

Flexible authentication solution for Rails with Warden.
http://blog.plataformatec.com.br/tag/devise/
MIT License
23.91k stars 5.54k forks source link

DisabledSessionError when using authenticate_user! api only #5443

Open mbackermann opened 2 years ago

mbackermann commented 2 years ago

Pre Check

Environment

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.

mbackermann commented 2 years ago

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.

morenocarullo commented 2 years ago

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 ?

arpu commented 2 years ago

@morenocarullo i use Rails.application.config.session_store :disabled and have the same Problem can you provide your FakeRakeSession Example?

morenocarullo commented 2 years ago

@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.

arpu commented 2 years ago

reference rails change https://github.com/rails/rails/pull/42231

souzagab commented 2 years ago

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

connortorrell commented 2 years ago

Any update on when this will be fixed?

morenocarullo commented 2 years ago

@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

NfoCipher commented 2 years ago

Did they accept the PR?

morenocarullo commented 2 years ago

@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..

KidA001 commented 2 years ago

Thank you @morenocarullo, using your fix as well. +1 for getting an official fix merged

morenocarullo commented 2 years ago

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.

morenocarullo commented 2 years ago

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.

NfoCipher commented 2 years ago

This: https://github.com/waiting-for-dev/devise-jwt/issues/235#issuecomment-1116864740 also seems to work.

VictorRubia commented 1 year ago

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.

england commented 1 year ago

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

styliii commented 1 year ago

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
thibpoullain commented 1 year ago

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
carlosantoniodasilva commented 1 year ago

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.

sidevesh commented 6 months ago

Any reason this is still held up ?