2012-01-09 13 views
8

私はDeviseを使用しており、顧客がX日以内に返されなかった場合には、ユーザーモデルのlast_sign_in_atに依存しています。しかし、私は最近、last_sign_in_atは、実際のフォームログインイベントが発生したときにのみ更新されることを発見しました。これは、ユーザーが覚えやすいという理由で自動的にログインするのとは異なります。Devise:rememberableは、last_sign_in_atがtrackableによって更新されないことを意味します。

ユーザがログインするたびに新しいログインセッション(新しいブラウザセッション)が更新されるようにするには、フォームを使用してログインしたか、覚えやすいクッキーによって自動的にログインしたかにかかわらず、 Deviseと互換性のある方法でこれを行うのですか?

答えて

5

追跡可能なフックはWarden's after_set_userフックです - これを簡単に解決するには、before_filterをsign_inに設定します。

この

を最適化することができますが、

before_filter proc{ sign_in(current_user, :force => true) } 

last_signed_in_atタイムスタンプを更新を使用するかどうかをテストします。マシューのソリューションを撮影

+1

before_filterはいつ呼び出されますか?私はそれぞれの要求には期待していませんが、そのセッションの初めての認証の前にのみですか?また、愚かな質問が、どこにbefore_filterを追加するのですか?私はそれをDeviseユーザーモデルに追加しようとしましたが、未定義のbefore_filterメソッドがありました。 –

+0

これは、各リクエストで実行されます。より良い解決策を実装する前に解決するかどうかを確認するのは、すばやく/汚れたデバッグステップでした。それをグローバルにしたいなら、それをどんなコントローラ、ApplicationControllerにも追加できるはずです。 – RobH

+3

こんにちはロブ、これは私が最後に行ったことです。a)ユーザがsign_inを強制する前にログインしていることを確認し、b)sign_in(強制)メソッドがセッションごとに1回だけ実行されるようにします。(言い換えれば、改行の代わりに、コメントは改行を許さない) 'before_filter proc {if user_signed_in? &&セッション[:logged_signin]; sign_in(current_user、:force => true);セッション[:logged_signin] = true; end} ' –

13

、私はコードが(セッションの前にいないオペレータに注意してください[:logged_signin]):次のようであるべきだと思いますが、また、そのcurrent_userモデルにupdate_tracked_fields!を使用することができます私の知る限り

before_filter :update_last_sign_in_at 

protected 

def update_last_sign_in_at 
    if user_signed_in? && !session[:logged_signin] 
    sign_in(current_user, :force => true) 
    session[:logged_signin] = true 
    end 
end 
+0

これはまだ最適なソリューションですか? –

+0

カスタムCookieパラメータを使用して、これが新規セッションか既存セッションかを確認しています。ヒントをお寄せいただきありがとうございます。私の場合、これはデビーズの内部を掘り起こす必要がないため、これはきれいなアプローチです。 –

-1

。以前のソリューションを拡張し

+0

'update_tracked_fields!'はリクエストをパラメータとして受け取ります。 deviseはIPを追跡するのでコントローラの 'current_user.update_tracked_fields!(request)'でこれを行うだけです。 –

2

Devise: rememberable means that last_sign_in_at is not updated by trackable

、それらの問題は通常、ユーザーがサインインすると、彼らは「二回のログイン」になるということでしょう。 last_sign_in_atcurrent_sign_in_atと同じ(またはほぼ同じ)値に設定します。 私のサイトでは、last_sign_in_atを使用して、前回の訪問時から何が起こったのかをユーザに知らせるため、やや正確である必要があります。また、+1ログイン回数を記録します。

また、ブラウザーウィンドウを閉じずに数日間ブラウザウィンドウを開いたままにする(したがって、セッションフラグをクリアしない)人がいます。メトリックなどの場合、このようなユーザーの動作によって時々current_sign_in_at時間がリフレッシュされると便利です。

以下の亜種がこれらの問題を改善します。しかし

class ApplicationController < ActionController::Base 
    before_filter :update_sign_in_at_periodically 
    UPDATE_LOGIN_PERIOD = 10.hours 

    protected 

    def update_sign_in_at_periodically 
    if !session[:last_login_update_at] or session[:last_login_update_at] < UPDATE_LOGIN_PERIOD.ago 
     session[:last_login_update_at] = Time.now 
     sign_in(current_user, :force => true) if user_signed_in? 
    end 
    end 
end 

、私が考案3.2.4を使用して、上記を試したとき、私はクッキーによってそれ自動ログインは(ログイン回数+1とcurrent_sign_in_atが設定されている)新しいログインを入手できます。だから、セッションを開いたままにしているユーザであっても、定期的にトラッキングを更新したいという問題が残っています。

class ApplicationController < ActionController::Base 
    before_filter :update_sign_in_at_periodically 
    UPDATE_LOGIN_PERIOD = 10.hours 

    protected 

    def update_sign_in_at_periodically 
    # use session cookie to avoid hammering the database 
    if !session[:last_login_update_at] or session[:last_login_update_at] < UPDATE_LOGIN_PERIOD.ago 
     session[:last_login_update_at] = Time.now 
     if user_signed_in? and current_user.current_sign_in_at < 1.minute.ago # prevents double logins 
     sign_in(current_user, :force => true) 
     end 
    end 
    end 
end 
関連する問題