Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
527 views
in Technique[技术] by (71.8m points)

ruby on rails - Devise sessions expiring too fast (hours, not days)

I'm moving this from an issue on the Devise repo as I don't know that it's actually a bug yet. I'm hoping someone can help me understand why my devise sessions are timing out so quickly.

Environment

Ruby 2.7.2 Rails 6.1 Devise 4.7.3

Current behavior

My goal was to persist sessions for around 30 days before requiring the user to login again. With stock devise, no inviteable, I was seeing properly persisted session times on my desktop browsers but short sessions, (expiring in days, sometimes hours) on mobile devises. I realized maybe I needed to be using :timeoutable

I installed :timeoutable against a User model, enabled and set the config.timeout_in in 29.days in devise.rb. Except now with :timeoutable configured instead of longer 29.day sessions, all browser sessions are closing out after around hour or two.

Expected behavior

Session should persist for 29.days before requiring the user to login again.

I feel like I'm missing something obvious but I can't find it. Is :timeoutable not the right way to achieve this?

Update:

This issue resolved itself after moving my application from a subdomain to the root domain. This isn't really any answer but I wanted to add it here for context. Beyond that I think the next best answer would have been to adjust the rails native cookie store.

Regardless, I'm still unconvinced timeoutable is working properly.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Sessions are downright confusing because we use the same term for so many different things.

The first is the low level ActionDispatch::Session mechanism provided by Rails. This consists of a set of middleware that links a session identifier (which identifies a client connected to the application accross requests) with a session storage. This can really persist any kind of simple serializable object across requests and while its most commonly used for authentication it also does other stuff like flash messages.

The default session storage is ActionDispatch::Session::CookieStore as its by far the fastest but there are also several options to store the session data on the server. You set the expiry time of the session storage cookies through:

Rails.application.config.session_store :cookie_store, expire_after: 30.days

Then there is what you could call authentication sessions which is really just storing a claim (an id) in the stash so that the user does not have to provide credentials (email, password) in each request. In Devise all this stuff is handled by the Warden gem. When you log in Warden stuffs that user id into the session storage and deletes it when you log out. This logs you in/out when using a specific client. There is no actual timeout by default here - it lasts as long as the session storage cookie.

This is where the Timeoutable module comes in. It stores an additional timestamp along with the id and if the timestamp has expired Warden will reject the user id stored in the session and delete it. Not that if the cookie actually expired before this the whole process is moot.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...