Files
crmPRO/docs/plans/2026-02-28-remember-me-multi-device-design.md

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:

  • id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
  • user_id INT UNSIGNED NOT NULL, indexed
  • token_hash CHAR(64) NOT NULL, unique
  • created_at DATETIME NOT NULL
  • last_used_at DATETIME NULL
  • user_agent VARCHAR(255) NULL
  • ip VARCHAR(45) NULL

Rationale:

  • Store only token_hash (SHA-256 of raw token) to avoid storing bearer tokens in plain text.
  • Use last_used_at for retention and auditing. If null, fall back to created_at.

Login Flow

  1. When user logs in with "Zapamiêtaj mnie":
    • Generate random token (64 hex).
    • Store hash = sha256(token) in users_remember_tokens with metadata and timestamps.
    • Set cookie to the raw token with expiry +1 year and existing security attributes.
  2. When user logs in without "Zapamiêtaj mnie":
    • Do not create a token.
    • Existing cookie is cleared.

Auto-Login Flow

  1. If no session and cookie exists:
    • Hash cookie value with SHA-256.
    • Look up users_remember_tokens by token_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 (or created_at if last_used_at is 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.