How Refresh Tokens Work

A refresh token in an OAuth setup using Json Web Tokens (JWT) is used to request a new access token. Because access tokens are short lived (to minimize the impact of a token being exfiltrated), a long lived refresh token is commonly used to, for example, stay logged into an app rather than need to log in every n minutes (the length of the access token).

Why have two tokens? In web apps this provides an additional layer of security and a better access story for your auth service (for high traffic app). Access tokens have a short life and the signed token is verified on every request (CPU bound), a refresh token affords a chance for the auth service to cut off access (using a deny list in a database i.e. IO bound) and is also stored separately (HttpOnly cookie) to prevent cross-site-scripting (XSS) attacks. This also improves scalability, authentication happens less frequently (at login time and token refresh time) which can reduce load on an auth service.

The refresh token should be treated differently because it has a longer expiry. It should be stored in a more secure way to prevent leaking it. In the browser that means storing it in an HttpOnly, Secure, and SameSite (to prevent CSRF attacks) cookie in the browser which can not be accessed from JS and refresh token rotation. This makes it possible to “refresh” an access token by making a request and including the cookie (using fetch with credentials: 'include').

See also: