Skip to content

feat: use HTTP-only cookies for auth tokens to enable SSR #51

@rorybyrne

Description

@rorybyrne

Summary

Currently, auth tokens are stored in localStorage, which means the server cannot access them during SSR. This causes the auth UI (login button vs user menu) to "pop in" after hydration.

Current Behavior

  1. Server renders page with no auth state (can't access localStorage)
  2. Browser hydrates with loading state
  3. useEffect reads localStorage, finds tokens
  4. UI re-renders with authenticated state
  5. User sees profile button "pop in"

Desired Behavior

Server should know auth state during SSR and render the correct UI immediately, with no pop-in.

Solution

Store auth tokens in HTTP-only cookies instead of localStorage:

Backend changes:

  • Set access_token and refresh_token as HTTP-only, Secure, SameSite cookies on login/callback
  • Read tokens from cookies in auth middleware
  • Clear cookies on logout

Frontend changes:

  • Remove localStorage token storage
  • Credentials included automatically via credentials: 'include'
  • Server components can check auth via cookies

Benefits:

  • No hydration mismatch for auth UI
  • More secure (HTTP-only cookies not accessible to XSS)
  • Simpler frontend code (no manual token management)

Trade-offs:

  • CSRF protection needed (but we already have signed state tokens)
  • Cookies sent on every request (minor overhead)

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew functionality

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions