当用户通过标准Devise控制器注销时,Devise会破坏整个会话存储,而不仅仅是它自己的数据。有什么方法可以避免这种行为吗?我还有其他不相关的数据应该保留。
session[:my_var] = "123"
通过设计退出...
puts session[:my_var]
# => nil
答案 0 :(得分:43)
在持续版本的设备中,没有必要覆盖会话控制器,而只需使用:
config.sign_out_all_scopes = false
在devise.rb
文件中获取所需的行为。
答案 1 :(得分:19)
destroy
的{{1}}¹方法包含以下行:
SessionsController
signed_out = Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
²方法在没有任何参数的情况下调用sign_out_all_scopes
,warden.logout
³方法调用sign_out
。
warden.logout(scope)
⁴方法的文档说明:
logout
结论:# Logout everyone and clear the session
env['warden'].logout
# Logout the default user but leave the rest of the session alone
env['warden'].logout(:default)
应该在给定特定范围时保留会话。但是,我认为没有办法做到这一点。 sign_out
首先始终,如果无法将任何用户注销,则只返回sign_out_all_scopes
。
我建议在问题跟踪器上使用posting a feature request或开发自己的身份验证解决方案。 Rails现在提供has_secure_password
,而现在人们似乎都在为后者而努力,以避免遇到这些问题。
¹Devise::SessionsController#destroy
²Devise::Controllers::Helpers#sign_out_all_scopes
答案 2 :(得分:15)
您可以覆盖Devise的SessionController,就像我保留购物车一样:
<强> sessions_controller.rb 强>
class SessionsController < Devise::SessionsController
def destroy
order_id = session[:order_id]
super
session[:order_id] = order_id
end
end
<强>的routes.rb 强>
devise_for :users, :controllers => { :sessions => "sessions" }
答案 3 :(得分:2)
除了马修斯。声明
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
考虑到签署多个角色的可能性,可能是最好的一般注销声明。如果您的用户只是作为一个角色登录,并且您希望在注销时保留其余会话,那么最简单的方法是:
$ git clone git://github.com/plataformatec/devise.git
$ cd devise
$ git branch my_devise
$ git checkout my_devise
在编辑器中打开app / controllers / devise / sessions_controller.rb。在方法destroy中,替换
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
与
signed_out = sign_out(resource_name)
保存并退出编辑器并执行
$ git commit -am "remove only warden data from session on logout, preserve other data."
在项目的Gemfile中,描述依赖于
的设计gem 'devise', :path => "[YOUR PATH]/devise", :branch => "my_devise"