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
→ 無事マージされた