AcegiプラグインのRememberMe機能の使い方

やっと理解したので、忘れないようにメモ。

経緯

Acegiプラグインの用意してくれているログイン画面にrememberMeというチェックボックスがあったんですが、なんだかよく分からなかったので、とりあえずオフにしたまま、某アプリを社内でローンチしました。


で、しばらくたって、ユーザから「ログインがメンドイ」「ブラウザを再起動するとログインしなおさないといけない」というクレームがあがってきまして。


「なんでやねん!次の日までセッション持つようにしてるっちゅーねん」「おれはFirefox3だけど、次の日でもフツーに使えとるわ!」という感じで説明してると、ぞくぞくとオレもだめだよ報告が飛び込んできて、オレ涙目。

いや、別に泣いてなんかないけど。


どうやら、クッキー自体がブラウザの終了を乗り越えて生き延びれるようにはなっていなかった模様。

自分は、タブ状態を保存する機能を使ってたので、いったんブラウザを閉じてもクッキーが保存されていたというだけだったようです。


確かに家に帰ってきてFirebugsで確認しても、ログイン時にSet-Cookieヘッダがとんでません。
Expiresで有効期限引き延ばしてあげないと、ブラウザ終了とともにクッキーは蒸発してしまいます。
サーバ側でいくらセッションを長くしようが、クッキーが消えてしまえば、セッションにつながりません。使われないセッションは、ただの無駄メモリ喰らいです。

Acegiのバージョン

Acegi0.3を使ってます。

Acegiプラグインのデフォルト状態

Acegiプラグインの用意してるログイン画面には、

が表示されています。


実は、このrememberMeの効果がいまいち分からなかったので、分からないものには手を出しちゃいかん、という祖父の遺言に従ってコメントアウトしてました。


じいちゃん、明日調べたらONにするよ、と。

ログイン画面のチェックボックスの意味

Firebugsでリクエスト/レスポンスを確認しながらぽちぽち試してみて、やっとわかりました。


これをチェックしてログインすることで、ログイン時のレスポンスとして、Expires付きのSet-Cookieヘッダが返ってきてるんですね。


Expires(有効期限)は、SecurityConfig.groovyというAcegiプラグインの設定ファイルで調整できます。


この設定ファイルは、Acegプラグインをインストールした後に、grails create-auth-domains を実行したときに grails-app/conf/SecurityConfig.groovy に生成されるものです。
バージョンごとに内容が結構変わっているようです。


とりあえず、さっき試しにサンプルアプリにAcegiプラグインをインストールしてみたら、Acegiプラグインのバージョンは0.5.1になっていて、 grails-app/conf/SecurityConfig.groovy はほとんどからっぽの状態でした。


そんなときは、 plugins/acegi-0.5.1/grails-app/conf/DefaultSecurityConfig.groovy から必要な部分をSecurityConfig.groovyにコピーしてきて、書き換えればOKです。
grails-app/conf/SecurityConfig.groovy の方が優先なので、上書きできます。


もちろん、デフォルトのままで変更しなくてもいいなら、わざわざそんなことをする必要もありません。


さて、デフォルトでは、Cookieは14日間有効になっています。

    /** rememberMeServices */
    cookieName = 'grails_remember_me' 
    alwaysRemember = false
    tokenValiditySeconds = 1209600 //14 days        ←これが有効期限
    parameter = '_spring_security_remember_me'
    rememberMeKey = 'grailsRocks'


このように、ユーザ自らクッキーを長期保持するかどうか選べるようになっているわけです。
Acegi++。


それを、チェックボックスを隠したりするもんだから、ユーザに怒られるのも当然なわけです。
nobeans--。

設定ファイルのalwaysRememberの意味

さて、設定ファイルをながめていると、alwaysRememberという項目をみつけました。

    /** rememberMeServices */
    cookieName = 'grails_remember_me' 
    alwaysRemember = false                          ←これ
    tokenValiditySeconds = 1209600 //14 days
    parameter = '_spring_security_remember_me'
    rememberMeKey = 'grailsRocks'


これをtrueにすると、強制的にExpires付きのSet-Cookieが送られるようになります。


ユーザがチェックボックスをつけてもつけなくても関係ありません。
問答無用です。

あるべき姿(たぶん)

つまり、以下の二択となります。


まちがっても、

こんな設定にしてはいけません。

まとめ

じいちゃんッッ、明日って今さッ!