rails2系はえらい子なのでCSRFを自動的に防止してくれます。
app/controllers/application.rbに
protect_from_forgery # :secret => 'ないしょ'
とかいとくだけでget以外のときに自動的にトークンを埋め込み不正な遷移かどうか確認してくれます。なんとも出来る子です。しかし、この機能とセッションタイムアウトの設定を同時に使うとなんともエラーが発生してしまう。
この機能はaction_controller/request_forgery_protection.rbの中でセッションの中のダイジェストとクライアントから送られてきたダイジェストが同じかどうかを判断しているのですが、セッションタイムアウトが働いているとこの時点でセッションが空っぽになっている。なのでCSRFエラーとなりActionController::InvalidAuthenticityTokenが発生してしまう。
# No secret was given, so assume this is a cookie session store. def authenticity_token_from_cookie_session session[:csrf_id] ||= CGI::Session.generate_unique_id session.dbman.generate_digest(session[:csrf_id]) end
どちらかというとこの評価は後にしてちゃんとセッションタイムアウトエラーを出したいな〜とおもってみていたらRoRWikiによさげな記事があった
http://techno.hippy.jp/rorwiki/?HowtoChangeSessionOptions
んでこんなのを書いてbefore_filterの権限管理の前に入れてみたところセッションタイムアウトはちゃんと実施されCSRFの精査もうまく行った。
def set_session_expiration return unless session reset_session if session['expiry_time'] && session['expiry_time'] < Time.now session['expiry_time'] = Time.now + 5.minutes end
しかもクッキー自体の生存期間が未設定になるのでクライアントプロセス内にしか保存されないようになるのでいい
何事にも先達はあらまほしきことかな