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-cookieto 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 intracker-admin/src/api/client.ts