简体   繁体   中英

Devise: current_user is nil after sign in

I've run into a very confusing issue with Devise where I'm able to successfully login but appear to be logged out immediately afterwards. Putting a breakpoint in the sessions#create action I can see that current_user is set accurately, however, once sessions#create redirects to another controller current_user is nil. What could cause this behavior?

sessions_controller:

class SessionsController < Devise::SessionsController
  def create
    respond_to do |format|
      format.html do
        self.resource = warden.authenticate!(auth_options)
        sign_in(resource_name, resource)
        # at this point current_user is set appropriately
        redirect_to users_path
      end
    end
  end

  def destroy
    signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))

    respond_to do |format|
      format.html do
        redirect_to :destroy_session_path
      end
      format.json do
        render status: 201
      end
    end
  end
end

users_controller:

class UsersController < ActionController::Base

  layout 'layouts/application'

  def index
     # current_user is nil here
  end
end

routes:

Rails.application.routes.draw do
  devise_for :users, controllers: { sessions: 'sessions' }

  devise_scope :user do
    scope '/admin' do
      resources :users
    end
  end
end

I am seeing the exact same issue. Any resolution for this?

My debug output:

After a successful login using devise here is the debug from session controller create method:

[2021-05-14 09:42:15] INFO -- ======================= SessionsController: User deviseuser@somesite.com signed-in from Web browser.

Followed by:

[2021-05-14 10:16:03] INFO -- Completed 302 Found in 102ms (ActiveRecord: 0.0ms)
[2021-05-14 10:16:03] INFO -- Started GET "/" for 12.23.34.56 at 2021-05-14 09:42:15 -0700
[2021-05-14 10:16:03] INFO -- Processing by RuntimeController#index as HTML

[2021-05-14 10:16:03] DEBUG -- Warden::Manager.after_failed_fetch: User nil   opts: {:scope=>:user}
[2021-05-14 10:16:03] DEBUG -- authenticate_user!:  before 'super' user_signed_in? = false   current_user = nil
[2021-05-14 10:16:03] INFO -- Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms)
[2021-05-14 10:16:03] INFO -- Warden::Manager: before_failure  opts: {:scope=>:user, :action=>"unauthenticated", :message=>nil, :attempted_path=>"/"}.

So after the successful login after_sign_in_path_for correctly returns the root "/" path for the redirection.
The RuntimeController is correctly identified via routes.rb as the handler for the route path. However, things go south at this point. As the OP pointed out the current_user somehow is reset to nil after the successful login.

According to the Warden inline comments the method Warden::Manager.after_failed_fetch is

# A callback that runs if no user could be fetched, meaning there is now no user logged in.

This leads to the Completed 401 Unauthorized output.

Note also that the User record in the mysql database is consistent with signed_in = 1 and other fields being appropriately set.

I should point out that this code has been working properly for many years. Obviously there has been an update that broke the system: ie, ruby, rails or a gem that is no longer compatible. However, I can't see where the difference is.

RoR config

$ rails -v
Rails 5.0.1
$ ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-linux]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM