2012-04-14 5 views
21

Wygląda na to, że użytkownik wylogowuje się za pomocą standardowych kontrolerów Devise, Devise niszczy cały magazyn sesji, a nie tylko własne dane. Czy istnieje sposób na uniknięcie tego zachowania? Mam inne nieistotne dane, które powinny być przechowywane.Zatrzymaj tworzenie z sesji czyszczącej

session[:my_var] = "123" 

wylog poprzez devise ...

puts session[:my_var] 
# => nil 

Odpowiedz

18

Sposób destroy đ z SessionsController zawiera następujące linie:

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

sign_out_all_scopes ² sposób wymaga warden.logout bez argumentów i metoda wywołuje sign_out ³ wywołania metody.

dokumentacji logout ⁴ stanach metoda:

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

Wniosek: sign_out powinien zachować sesję kiedy otrzymuje określony zakres. Jednak nie widzę sposobu, aby to zrobić. sign_out_all_scopes jest zawsze zawsze nazywany jako pierwszy i zwróci tylko false, jeśli nie może zarejestrować żadnego użytkownika.

Polecam albo posting a feature request na ich trackerze problemów lub opracowanie własnego rozwiązania do uwierzytelniania. Rails zapewnia teraz has_secure_password, a obecnie wydaje się, że ludzie wybierają ten drugi sposób, aby uniknąć problemów.


¹ Devise::SessionsController#destroy

² Devise::Controllers::Helpers#sign_out_all_scopes

ł Devise::Controllers::Helpers#sign_out

Warden::Proxy#logout

+2

Dziękuję za wszystkie wysiłki, Matheus. – bloudermilk

+0

Wygląda na to, że uległo zmianie w kodzie, a twoje linki nie zawierają wartości mieszania zatwierdzenia. Dzisiaj 'Devise.sign_out_all_scopes' jest boolean: https://github.com/plataformatec/devise/blob/ee01bac8b0b828b3da0d79c46115ba65c433d6c8/lib/devise.rb#L220 –

2

Oprócz Mattheus. Oświadczenie może być najlepszym ogólnym wylogowaniem, biorąc pod uwagę możliwość zalogowania się w wielu rolach. Jeśli dla ciebie wypadku Twój użytkownik jest właśnie podpisał się jako jedną rolę, a chcesz zachować resztę sesji SignOut, najprostszym sposobem jest zrobić:

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

Otwórz app/controllers/opracowania/sessions_controller.rb w twoim edytorze.W metodzie zniszczyć, wymienić

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

z

signed_out = sign_out(resource_name) 

Zapisz i zamknij Edytor i zrobić

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

w Gemfile swojego projektu, opisuje zależność opracować jak

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

Mogłeś zrobić t zastąpić opracować za SessionController, jak ja się zachować Koszyk:

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

Świetne proste rozwiązanie! Dziękuję za Twój wkład. – bloudermilk

+0

Proste rozwiązanie, nie zadzieraj z oprogramowaniem Devise, więc ryzyko nieoczekiwanego zachowania jest bardzo niskie. – Puce

+0

Chciałbym, żeby to działało, gdy program użyje funkcji Timeoutable. ta metoda nigdy nie jest hitem :( – MilesStanfield

40

W trwa wersje opracowania jest nie jest konieczne zastąpienie kontrolera sesji, zamiast tego można po prostu użyć:

config.sign_out_all_scopes = false 

W pliku devise.rb, aby uzyskać pożądane zachowanie.

+0

+1, potrzebna dokładnie to! –