停止设置清除会话

当用户通过标准Devise控制器注销时,Devise会破坏整个会话存储,而不仅仅是它自己的数据。 有什么方法可以避免这种行为吗? 我还有其他不相关的数据应该保留。

session[:my_var] = "123" 

通过设计退出…

 puts session[:my_var] # => nil 

SessionsController destroy¹方法包含以下行:

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

sign_out_all_scopes方法warden.logout没有任何参数的情况下调用warden.logoutsign_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 ,如果无法将任何用户注销,则仅返回false

我建议在问题跟踪器上发布function请求或开发自己的身份validation解决方案。 Rails现在提供has_secure_password ,现在人们似乎都在为后者而努力,以避免遇到这些问题。


Devise::SessionsController#destroy

Devise::Controllers::Helpers#sign_out_all_scopes

Devise::Controllers::Helpers#sign_out

⁴Warden Warden::Proxy#logout

在设备的持续版本中,覆盖会话控制器不是必需的,而是可以使用:

 config.sign_out_all_scopes = false 

devise.rb文件中获取所需的行为。

您可以像我保留购物车一样覆盖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" } 

除了马修斯。 该声明

 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"