2.4 KiB
2.4 KiB
Remember-Me Multi-Device Tokens Design (2026-02-28)
Context
After the security changes on 2026-02-26, remember-me uses a single users.remember_token value. This breaks multi-browser usage because each login overwrites the previous token. The goal is to allow unlimited concurrent remember-me sessions across devices and browsers, with retention cleanup for tokens older than 6 months.
Goals
- Allow unlimited concurrent remember-me sessions per user.
- Store only hashed tokens in the database.
- Keep existing cookie security attributes (
Secure,HttpOnly,SameSite=Lax). - Clean up tokens older than 6 months.
Non-Goals
- Reworking the entire authentication system.
- Introducing refresh-token or JWT flows.
Data Model
Add a new table users_remember_tokens:
idINT UNSIGNED AUTO_INCREMENT PRIMARY KEYuser_idINT UNSIGNED NOT NULL, indexedtoken_hashCHAR(64) NOT NULL, uniquecreated_atDATETIME NOT NULLlast_used_atDATETIME NULLuser_agentVARCHAR(255) NULLipVARCHAR(45) NULL
Rationale:
- Store only
token_hash(SHA-256 of raw token) to avoid storing bearer tokens in plain text. - Use
last_used_atfor retention and auditing. If null, fall back tocreated_at.
Login Flow
- When user logs in with "Zapamiêtaj mnie":
- Generate random token (64 hex).
- Store
hash = sha256(token)inusers_remember_tokenswith metadata and timestamps. - Set cookie to the raw token with expiry +1 year and existing security attributes.
- When user logs in without "Zapamiêtaj mnie":
- Do not create a token.
- Existing cookie is cleared.
Auto-Login Flow
- If no session and cookie exists:
- Hash cookie value with SHA-256.
- Look up
users_remember_tokensbytoken_hash. - If found, load user, set session, update
last_used_at. - If not found, clear cookie.
Retention
- Delete tokens older than 6 months based on
last_used_at(orcreated_atiflast_used_atis null). - Trigger cleanup during login and auto-login paths to avoid extra jobs.
Error Handling
- Missing or invalid token in DB results in clearing the cookie and continuing to login screen.
- No user row for token is treated as invalid and cleaned.
Testing
- Integration test: login with remember-me sets cookie and inserts token row.
- Integration test: auto-login succeeds from cookie after session is cleared.
- Retention test: tokens older than 6 months are removed on login.