analytics icon indicating copy to clipboard operation
analytics copied to clipboard

Implement token-based sessions

Open zoldar opened this issue 1 year ago • 1 comments

Changes

Follow-up to https://github.com/plausible/analytics/pull/4452 implementing token-based sessions.

  • A new table is added for storing sessions called user_sessions and used by Auth.UserSession schema
  • The session struct stores user reference, token (randomly generated on creation), last_used_at and timeout_at timestamps
  • Inactive session timeout is kept at 14 days, like before, just managed server-side
  • New user sessions refresh is managed by a new plug, UserSessionTouch which also converts existing legacy sessions to new ones on the go
  • There's a CleanUserSessions background job cleaning timed out sessions with an additional grace period of 7 days, just in case (sessions, when retrieved are always filtered by timeout, so that's not an issue)
  • Retrievals of legacy sessions is logged with a warning. Logs will be scanned for occurrences to determine whether rate of legacy sessions goes down towards zero during/after 14 day period as expected
  • Device name is detected using logic largely copied from Ingestion.Event pipeline. I have decided to not DRY these as they serve very different purposes.

TODO

  • [x] properly refresh valid and dispose of expired sessions
  • [x] instrument retrievals of legacy session cookie (accomplished with simple logging)
  • [x] more tests
  • [ ] extract migration to a different PR (may be done post-review)

Tests

  • [x] Automated tests have been added

Changelog

  • [x] Entry has been added to changelog

Documentation

  • [x] This change does not need a documentation update

Dark mode

  • [x] This PR does not change the UI

zoldar avatar Aug 22 '24 13:08 zoldar

Preview environment👷🏼‍♀️🏗️
PR-4463

github-actions[bot] avatar Aug 26 '24 11:08 github-actions[bot]

@ukutaht I have revised session retrieval and modified logic so that session, user and last subscription are always fetched in a single query. I have also modified plug pipelines interacting with session to ensure they don't refetch the session or user unless necessary.

By the way, I have noticed that our external API endpoints (/api/event included) have :fetch_session and AuthPlug in their pipeline - I have removed both as none of those endpoints need the session (I'll do some double-checking for that still).

This limits the number of session related queries to minimum. When I open funnel settings, I can see 2 SELECTs of user session (one for dead view and one for live view, we can't get around that), and one UPDATE for user_session (via UserSessionTouch). All else is related to validating site access permission (user role, site membership etc.). If we want to address those, I'd opt for doing that in a separate PR.

zoldar avatar Aug 29 '24 13:08 zoldar

@aerosol @ukutaht all feedback so far applied and PR ready for re-review.

zoldar avatar Sep 02 '24 10:09 zoldar