Rails の session の有効期限を無期限にする

2016年03月05日

WikiNoteに閲覧履歴機能つけたりした - 9mのパソコン日記

WikiNoteというWebサービスに、閲覧したことのあるページ一覧を表示するという機能があります。このサービスにはユーザー登録がないので、Rails でいうところの session.id に閲覧履歴を紐付けるということをやるのですが、ブラウザを再起動するごとに session がリセットされてしまっては使いものになりません。というわけで、session を永続化したという話。

Rails で session を永続化する方法

config/initializers/session_store.rb を編集して、config.sessionstore に遠い未来の expireafter を渡します。この sessionstore.rb は Rails 5 の例だけど、initializers に置いてある事と expiresafter のオプションはかなり前の Rails から変わっていないとおもう。

# Be sure to restart your server when you modify this file.

Rails.application.config.session_store :cookie_store, key: '_appname_session', expire_after: 20.years

これでブラウザを再起動しても session が切れることはなくなる。厳密には無期限ではないが、アクセスする度に20年後に期限が伸ばされるので、ほぼ無期限といって差し支えない。

ちなみにここで20年を指定したのは、cookies.permanent といういかにも cookie を永続化しそうなメソッドが20年を設定しているからです。

https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/cookies.rb#L480

そもそも cookie を永続化するというのは

Webブラウザの cookie にはそもそも一生消えないという設定値はないらしい。ブラウザの再起動で消えるセッションクッキー(expires 未設定 or 0)、もしくは有効期限を設定した cookie しかない。よって永続化のようなことをしたい場合20年後に切れるというようにしてやる。どちらにしろユーザーが自分でブラウザの設定をいじって cookie を消すということはできる。

他のサイトはどうしてるの

Railsで動いてるサイトの cookies をパラパラ見てみた。各サイト使ってる cookie は1つじゃなかったが、Railsのそれっぽいのを抜き出してご紹介。

Cookpad cookie: myappsession expires: セッション

Github cookie: user_session expires: 2週間後くらい

Airbnb cookie: airbedsession_id expires: 1ヶ月後くらい

MoneyForward cookies: moneybooksession expires: セッション

Heroku cookies: heroku_session expires: 1ヶ月後くらい

Hulu cookies: hulusession expires: 3年後くらい

結構バラバラだった、expires_after を設定しているサイトが多そう。

ここのセッション名、Rails プロジェクトを作成するときの最初の名前がデフォルトで付くから、どういう名前でコードを書き始めたのか分かる場合があって面白い。Cookpad の場合 rails new myapp で作り始めた名残がまだ残ってるように見受けられるし、MoneyForward は最初 MoneyBook という名前で呼ばれてたっぽい事が推測できる。Airbnb は最初、AirBed & Breakfast という名前でした。ドメインは変えられてもなかなかセッションキーの名前は変えられないもんね。