设计:current_user在登录后为零

时间:2018-03-02 17:56:41

标签: ruby-on-rails devise

我遇到了一个非常令人困惑的问题,我可以成功登录Devise,但之后会立即注销。在session #start动作中设置断点我可以看到current_user被准确设置,但是,一旦会话#create重定向到另一个控制器,current_user就是nil。什么可能导致这种行为?

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

路线:

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

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

1 个答案:

答案 0 :(得分:1)

我看到了完全相同的问题。对此有任何解决方案吗?

我的调试输出:

使用devise成功登录后,这里是会话控制器的调试create方法:

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

关注:

[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=>"/"}.

所以登录成功后after_sign_in_path_for正确返回了重定向的根“/”路径。
RuntimeController 通过 routes.rb 正确识别为路由路径的处理程序。 然而,事情在这一点上向南。正如 OP 所指出的,在成功登录后,current_user 不知何故被重置为 nil。

根据 Warden 内联注释,Warden::Manager.after_failed_fetch 方法是

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

这会导致 Completed 401 Unauthorized 输出。

还要注意mysql数据库中的User记录与signed_in = 1一致,其他字段设置适当。

我应该指出,这段代码多年来一直正常工作。显然有一个更新破坏了系统:即不再兼容的 ruby​​、rails 或 gem。但是,我看不出区别在哪里。

RoR 配置

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