Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop Devise from clearing session

It seems when a user logs out via standard Devise controllers, Devise destroys the entire session store, not just its own data. Is there any way to avoid this behavior? I have other irrelevant data that should be kept around.

session[:my_var] = "123"

Log out via devise...

puts session[:my_var]
# => nil
like image 276
bloudermilk Avatar asked Apr 14 '12 10:04

bloudermilk


3 Answers

In the lasts versions of devise it is not necesary to override the sessions controller, instead you can just use:

config.sign_out_all_scopes = false 

In the devise.rb file to get the desired behaviour.

like image 175
NanoOnTilt Avatar answered Sep 18 '22 15:09

NanoOnTilt


The destroy¹ method of SessionsController contains the following line:

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

The sign_out_all_scopes² method calls warden.logout without any arguments, and the sign_out³ method calls warden.logout(scope).

The documentation of the logout⁴ method states:

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

Conclusion: sign_out should preserve the session when given a specific scope. However, I don't see any way to do that. sign_out_all_scopes is always called first, and will only return false if it couldn't log any user out.

I recommend either posting a feature request on their issue tracker or developing your own authentication solution. Rails now provides has_secure_password, and these days people seem to be going for the latter in order to avoid running into these problems.


¹ Devise::SessionsController#destroy

² Devise::Controllers::Helpers#sign_out_all_scopes

³ Devise::Controllers::Helpers#sign_out

Warden::Proxy#logout

like image 24
Matheus Moreira Avatar answered Sep 17 '22 15:09

Matheus Moreira


You could just override Devise's SessionController, like I did to preserve a shopping cart:

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" }
like image 45
manafire Avatar answered Sep 19 '22 15:09

manafire