2012-04-14 19 views
21

Parece que cuando un usuario cierra la sesión a través de los controladores estándar Devise, Devise destruye toda la tienda de sesiones, no solo sus propios datos. ¿Hay alguna forma de evitar este comportamiento? Tengo otros datos irrelevantes que deberían mantenerse.Stop Devise de la sesión de borrado

session[:my_var] = "123" 

Desconectar través legado ...

puts session[:my_var] 
# => nil 

Respuesta

18

El método destroy ¹ de SessionsController contiene la siguiente línea:

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

El método sign_out_all_scopes ² llama warden.logout sin ningún argumento, y el método sign_out ³ llama al warden.logout(scope).

La documentación de los logout ⁴ estados de procedimiento:

# 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) 

Conclusión: sign_out debe preservar la sesión cuando se le da un alcance específico. Sin embargo, no veo ninguna manera de hacer eso. sign_out_all_scopes es siempre llamado primero, y solo devolverá false si no pudo registrar a ningún usuario.

Recomiendo posting a feature request en su rastreador de problemas o el desarrollo de su propia solución de autenticación. Rails ahora proporciona has_secure_password, y en estos días la gente parece estar buscando lo último para evitar encontrarse con estos problemas.


¹ Devise::SessionsController#destroy

² Devise::Controllers::Helpers#sign_out_all_scopes

³ Devise::Controllers::Helpers#sign_out

Warden::Proxy#logout

+2

Gracias por todos sus esfuerzos, Matheus. – bloudermilk

+0

Esto parece haber cambiado en el código y sus enlaces no tienen el hash de confirmación en ellos. Hoy, 'Devise.sign_out_all_scopes' es un booleano: https://github.com/plataformatec/devise/blob/ee01bac8b0b828b3da0d79c46115ba65c433d6c8/lib/devise.rb#L220 –

2

Además de Mattheus. La instrucción

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

es quizás la mejor declaración general de cierre de sesión, considerando la posibilidad de iniciar sesión con múltiples roles. Si, para usted caso, el usuario se acaba de iniciar sesión como un papel, y se desea conservar el resto de la sesión en signout, la forma más fácil es hacer:

$ git clone git://github.com/plataformatec/devise.git 
$ cd devise 
$ git branch my_devise 
$ git checkout my_devise 

aplicación Abrir/controladores/diseñar/sessions_controller.rb en tu editor.En el método de destruir, reemplace

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

con

signed_out = sign_out(resource_name) 

Guardar y salir editor y hacer

$ git commit -am "remove only warden data from session on logout, preserve other data." 

en el Gemfile de su proyecto, describir la dependencia de idear como

gem 'devise', :path => "[YOUR PATH]/devise", :branch => "my_devise" 
15

Usted podría jus t anulan SessionController de Diseñar, como lo hice para preservar un carrito de la compra:

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

¡Gran solución simple! Gracias por tu contribución. – bloudermilk

+0

Solución simple, no te metas con Devise trabajando, por lo que el riesgo de un comportamiento inesperado es muy bajo. – Puce

+0

desearía que esto funcionara cuando el dispositivo use timeoutable. este método nunca se golpea entonces :( – MilesStanfield

40

en las versiones de diseñar es dura no es necesario anular el controlador de sesiones; en su lugar, puede usar:

config.sign_out_all_scopes = false 

En el archivo devise.rb para obtener el comportamiento deseado.

+0

+1, ¡necesitaba exactamente esto! –

Cuestiones relacionadas