Oksa Satya.

April 6, 2026 · 7 min read

Secure JWT Authentication: Refresh Rotation, Reuse Detection, and HttpOnly Cookies

SecurityAuthJWTGo

JWT is often implemented in ways that actually reduce security: long-lived tokens stored in localStorage, with no way to revoke them. This is the authentication pattern I use so it stays convenient but remains accountable when a token leaks.

Short access, rotating refresh

The access token is short-lived so its abuse window is small. The refresh token lives longer and is used to obtain a new access token — but every time it is used, it rotates: the old refresh is revoked, a new one is issued.

This rotation is what gives the ability to detect theft. A token that should no longer be valid but is suddenly used again is a clear signal something is wrong.

Reuse detection: the signal of a stolen token

If a refresh token that has already rotated (and is therefore invalid) shows up again, chances are two parties hold the same token — the real user and a thief. The correct response: revoke the whole session chain and force a re-login.

Without rotation + reuse detection, a stolen token can be used silently until it expires naturally. With both, theft leaves a trail that can be acted on automatically.

Store in HttpOnly cookies, not localStorage

A token in localStorage can be read by any script on the page — one XSS hole and the token is gone. An HttpOnly + Secure + SameSite cookie cannot be read by JavaScript, moving the attack surface away from script injection.

The consequence is you need CSRF protection (e.g. a double-submit token), but that is a far better trade than leaving the token exposed to every third-party script.

Summary

Secure JWT auth is not about the library, but the pattern: short access, rotating refresh, reuse detection to catch theft, and storage in HttpOnly cookies with CSRF protection. Convenient to use, and revocable when needed.

Building something similar?

I take on projects and technical consulting around business systems.