https://github.com/redis-store/redis-rails#usage
には、
MyApplication::Application.config.session_store :redis_store, {
servers: [
{
host: "localhost",
port: 6379,
db: 0,
password: "mysecret",
namespace: "session"
},
],
expires_in: 90.minutes
}
という例があり、ほぼこのまま書いていたアプリがあった。
しかし、iPhoneのSafariで頻繁にログアウトされるという報告があり、改めて確認するとPCでもブラウザを再起動するとCookieが消えていた。
これはCookieにExpiresが付いていない時の挙動である。
そこで、真っ先に疑われたのがこの設定。Rails標準のCookieStoreでは、expire_afterを設定するのでそちらに変更してみたら解消した。
http://api.rubyonrails.org/classes/ActionDispatch/Session/CookieStore.html
とはいえREADMEに書いてあるので、中身を一応追ってみる。
1
redis-railsには実コードはないけどテストによると、session_storeの実体にはActionDispatch::Session::RedisStoreが使われる。
https://github.com/redis-store/redis-rails/blob/master/test/redis_rails_test.rb
2
ActionDispatch::Session::RedisStoreはredis-actionpackで定義され、Rack::Session::Redisを継承している。
https://github.com/redis-store/redis-actionpack/blob/master/lib/action_dispatch/middleware/session/redis_store.rb
3
Rack::Session::Redisはredis-rackで定義され、Rack::Session::Abstract::IDを継承している。
https://github.com/redis-store/redis-rack/blob/master/lib/rack/session/redis.rb
4
Rack::Session::Abstract::IDはrackで定義され、さらにRack::Session::Abstract::Persistedを継承している。
https://github.com/rack/rack/blob/master/lib/rack/session/abstract/id.rb
(Persistedも同一ファイルに定義)
ここにexpire_afterはあるが、expires_inは見当たらない。
CookieStoreは?
ActionDispatch::Session::AbstractStoreを継承して、それがさらにRack::Session::Abstract::Persistedを継承している。
https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
つまり結局Rack::Session::Abstract::Persistedが使われる。クラス階層の途中でexpires_inを見てそれらしき処理をしてるクラスがいない場合、READMEが間違っている、でよさそう。
ぷるり出してみようかな。
→ 出してみた https://github.com/redis-store/redis-rails/pull/64
→ 無事マージされた