class

KemalIdentity::Sessions::RememberService

Inherits Reference < Object

"Keep me signed in", done so that theft is detectable.

Not a long-lived session

docs/02-security-model.md is explicit that this must not be "an ordinary session with a 30-day expiry". That would be a bearer secret sitting in a browser for a month with no way to notice it had been copied.

Instead every token is single-use and rotates on presentation, and every token descended from one login shares a family. After a thief uses a stolen cookie the token is spent, so when the real user next presents their copy it is a replay — and the reverse if the user gets there first. Either way somebody presents a spent token, and that is the signal.

Restored sessions are weaker on purpose

A session restored here sits at AssuranceLevel::Remembered, below Password, and Principal#fresh? returns false for it however recently it was restored. Possession of a cookie is not the presence of the account holder. Anything sensitive calls require_fresh! and gets a real re-authentication.

Constructors

new(remember : RememberRepository, accounts : Accounts::Repository, sessions : Service, clock : Clock, random : RandomSource, notifier : Accounts::Notifier | Nil = nil, ttl : Time::Span = 30.days)
Source

Instance methods

delete_expired

Disk reclamation. Correctness never depends on it — but note that sweeping early would break replay detection, since a spent token's row is the evidence.

Source
forget(family_id : String) : Int32

Stops remembering one browser. What a "log out" button should call alongside ending the session, or the next visit signs the user straight back in.

Source
forget_all(account_id : String) : Int32

Stops remembering every browser. The right response to a password change.

Source
forget_by_token(raw_token : String) : Int32

Stops remembering the browser holding this token, without spending it.

What logging out calls. Consuming the token would mark it used, and the same cookie arriving later would read as a replay — so a user who pressed "log out" would be told their cookie may have been stolen.

Source
remember(account : Accounts::Account) : IssuedRemember

Starts remembering this browser, after a real authentication.

Called only when somebody has just proved who they are with a password. Never from a restored session: chaining remembrance off remembrance would make the thirty days a rolling window that never closes.

Source
restore(raw_token : String | Nil) : RestoreOutcome

Restores a remembered login, rotating the cookie.

Returns NotRemembered for anything unusable, ReplayDetected when a spent token comes back, and Restored on success — with a new remember token that the caller must write alongside the session cookie.

Source