我遇到了一个非常令人困惑的问题,我可以成功登录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
答案 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]