Skip to content

JWT Refresh

This guide describes the current access-token refresh flow used by the API and frontend applications.

How It Works

  • Access tokens are short-lived and used for normal API requests
  • Refresh tokens are stored in an HttpOnly cookie
  • The backend exposes /api/v1/auth/refresh-cookie to issue a new access token
  • The frontend can restore a session when the tab becomes active again

Backend Flow

The backend refresh flow is centered around the refresh token cookie and the refresh endpoint. It validates the refresh token, issues a new access token, and returns it to the caller.

Frontend Flow

The frontend checks token expiry before requests and attempts refresh when needed. It also restores sessions after browser sleep or tab suspension by rechecking the token when the page becomes visible again.

The same refresh-cookie flow is used by the admin panel request client in tracker-admin/src/api/client.ts, including retrying 401 responses after refresh.

Configuration

Key settings:

ACCESS_TOKEN_EXPIRE_MINUTES = 240
REFRESH_TOKEN_EXPIRE_DAYS = 7
JWT_ISSUER = "tracker-api"
JWT_AUDIENCE = "tracker-clients"

The refresh cookie is configured as HttpOnly and uses SameSite=Lax.

Testing

Refresh behavior is covered by backend and frontend tests for:

  • token refresh endpoints
  • refresh cookies
  • concurrent refresh handling
  • expired-token recovery

Troubleshooting

  • If refresh fails, confirm the cookie is present and valid
  • If requests loop on authentication, make sure auth endpoints are excluded from refresh handling
  • If the admin panel logs out too often, verify it uses the same refresh pattern as the frontend
  • If the admin panel is not retrying after a 401, check the request interceptor in tracker-admin/src/api/client.ts