authlogic で、ユーザーの password を編集した直後に強制ログアウトされる件
イントロ
authlogic
でハマったネタ第二弾。
まとめると以下の様な感じ。
- authlogic でログインユーザーを作成
- よくある 名前と password で認証するユーザー
- ログインユーザーを編集する画面を作る
- password を編集可能にする
- ログインユーザーの password を更新すると、何故か強制的にログアウト状態になる
- ログインを要求する url に強制 redirect される
解決法
class User < ActiveRecord::Base acts_as_authentic do |c| c.session_class = UserSession end end
この解決方法はあくまで一例。
原因
authlogic
のログイン状態は、DB に保存されているpersistence_token
とsession[:user_credentials]
の一致により判定される。user_credentials
という session の key はログイン用のモデルによって変更の可能性あり
authlogic
で password を更新すると、強制的にpersistence_token
も再生成される- この時 session の値も再生成された文字列に更新しなければならない
- 設定が甘くて、password を更新した時に session の値が更新されなかったため、ログイン状態が維持されなかった
- authlogic がログイン画面にリダイレクト
のような感じ。
肝心の session の値も再生性された文字列で上書きしなければならない
設定は以下のメソッドで行っている。
恐らくこの値は true でなければいけないが、false になっているとこんなおかしな状況になる。
def update_sessions? !skip_session_maintenance && session_class && session_class.activated? && self.class.maintain_sessions == true && !session_ids.blank? && persistence_token_changed? end
今回私が遭遇したケースでは session_class
が何故か nil を返すようになっていたので、session が update されず、ログアウト状態になってしまっていた。
session_class について
session_class
とは
Authlogic::Session::Base
を継承した session クラスを返すメソッド- 普通は自動で判定される
User
がacts_as_authentic
ならUserSession
という風に
ので、普段は意識しなくていいはず。
例えば Admin
モデルを作って、Admin
専用の管理画面を作ろう、となった時に Session クラスを AdministratorSession
としてしまうと、session_class
を指定する必要がある。
設定を忘れるとこのような目にある。
まとめ
Authlogic::ActsAsAuthentic::SessionMaintenance::Methods#update_session?
メソッドを調べればよろし