Access token vs. refresh token
Two keys with different jobs: a short-lived one that opens API calls, and a long-lived one whose only job is minting more of the first.
See it
What it is
Two tokens, two jobs. The access token is the one you spend: it rides along on every API call in the Authorization header, lives 5 to 60 minutes, and is usually a signed JWT your API can verify by signature alone with no database round trip. The refresh token is the one you keep: it goes only to the auth server's token endpoint, lives days to months, and is usually an opaque random string whose hash sits in your database so it can be looked up and killed.
The split exists to buy two things that fight each other. Stateless access tokens make API calls fast, but you cannot un-issue them. So you keep their lifetime short enough that a leak has a small blast radius, and you hand out a separate, revocable, carefully-stored credential to cover the long tail of the session. Short and fast for calls, long and controllable for renewal.
Gotcha most people hit: revoking a refresh token does not log anyone out right away. Any access token already issued keeps working until it expires, which is the entire reason to keep that window at 15 minutes instead of 24 hours. Two related mistakes: sending the refresh token to your product API (it belongs to the auth server only), and stuffing both tokens in localStorage, which erases the security difference between them.
Ask AI for it
Set up a two-token auth scheme. Issue an access token as a JWT with a 15-minute expiry, containing sub, org id, roles, iss, aud, and jti, sent on every API request as 'Authorization: Bearer <token>' and verified locally with no database lookup. Issue a refresh token as a 32-byte random opaque string with a 30-day expiry, stored hashed server-side and delivered as an HttpOnly, Secure, SameSite cookie scoped to the refresh endpoint. Accept the refresh token at POST /auth/refresh only, never on resource routes, and return both a new access token and its expiry in seconds so the client can refresh proactively 60 seconds before expiry.