2012-04-14 12 views
21

ユーザーが標準のDeviseコントローラを介してログアウトすると、Deviseは自身のデータだけでなくセッションストア全体を破壊するようです。この動作を回避する方法はありますか?私は別の無関係なデータを保管しておくべきです。セッションをクリアすることを停止する

session[:my_var] = "123" 

SessionsController

puts session[:my_var] 
# => nil 

答えて

18

destroy¹方法は、次の行が含まれ...工夫を経由してログアウトします:sign_out_all_scopes²メソッドは引数なしwarden.logoutを呼び出し、

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

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です。常にが最初に呼び出され、ユーザーをログアウトできなかった場合はfalseが返されます。

私はposting a feature requestの問題追跡ツールまたは独自の認証ソリューションの開発を推奨します。 Railsは現在has_secure_passwordを提供しています。最近、これらの問題にぶち壊されることを避けるために、人々は後者に向かうようです。


はMattheusに加えDevise::SessionsController#destroy

²Devise::Controllers::Helpers#sign_out_all_scopes

³Devise::Controllers::Helpers#sign_out

Warden::Proxy#logout

+2

あなたの努力のおかげで、マテウス。 – bloudermilk

+0

これはコード内で変更されているように見え、リンクにはコミットハッシュがありません。今日、 'Devise.sign_out_all_scopes'はブール値です:https://github.com/plataformatec/devise/blob/ee01bac8b0b828b3da0d79c46115ba65c433d6c8/lib/devise.rb#L220 –

2

を¹しました。ステートメント

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

複数のロールでサインインする可能性を考慮して、おそらく最も一般的なログアウトステートメントです。あなたの場合のために、ユーザーがちょうど1つの役割として署名されている、とあなたがサインアウトのセッションの残りの部分を保持したい、場合は、最も簡単な方法は、実行することです。

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

オープンアプリ/コントローラ/ /工夫しますsessions_controller.rbをエディタで開きます。この方法では、破壊

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

signed_out = sign_out(resource_name) 

保存して終了し、エディタを交換し、プロジェクトのGemfileで

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

を行い、

ように工夫して依存関係を記述
gem 'devise', :path => "[YOUR PATH]/devise", :branch => "my_devise" 
15

jus私は、ショッピングカートを維持するために行ったようトン、考案者の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

素晴らしい簡単な解決策!あなたの貢献に感謝します。 – bloudermilk

+0

シンプルなソリューションでは、予期せぬ動作のリスクが非常に低いので、Deviseの作業を混乱させることはありません。 – Puce

+0

私はdeviseがtimeoutableを使用しているときにこれがうまくいきたいと思っています。この方法は決して命中しません:( – MilesStanfield

40

をセッションコントローラーをオーバーライドする必要はありませんが、代わりに次のものを使用することができます:

config.sign_out_all_scopes = false 

devise.rbファイルでは、目的の動作が得られます。

+0

+1、正確にこれが必要です! –

関連する問題