Auth Tools
Token Generator
Generate high-entropy access and refresh tokens, with expiry times, storage hashes, and a sample OAuth 2.0 response.
Understand the format
How Token Generator works
An opaque token is nothing but random bytes: its security comes entirely from being unguessable and from what the server stores next to it.
Opaque tokens versus JWTs
OAuth 2.0 does not say what an access token looks like. The specification calls it opaque to the client, and two designs dominate. An opaque token is a random string that means nothing on its own; the authorisation server keeps a record and looks it up on every request. A JWT is self-describing: the claims travel inside the token and any service holding the key can validate it without a database round trip.
The trade-off is revocation against lookup cost. An opaque token can be revoked instantly by deleting the row. A JWT stays valid until it expires, because nothing consults a database, which is why JWT access tokens are usually given short lifetimes and paired with a revocable refresh token. This page generates opaque tokens, which is the right default whenever you control the resource server and want revocation to be immediate.
Entropy is the whole security argument
A random token is safe only while guessing one is infeasible. 128 bits of entropy is the common floor and 256 bits is a comfortable default; the encoding you choose changes the length of the string but never its strength. 32 random bytes are 43 characters in Base64URL and 64 characters in hexadecimal, and both carry exactly 256 bits.
What matters far more than length is the source. The bytes here come from crypto.getRandomValues, the browser cryptographically secure generator. A token built from Math.random, a timestamp, a counter, or a hash of a user id is predictable, and predictable tokens have been the root cause of a long line of account-takeover bugs.
Store the hash, never the token
Treat tokens the way you treat passwords: the server should keep only a SHA-256 of the token, compare digests on each request, and show the plaintext exactly once at issue time. If the token table then leaks, the attacker has digests rather than working credentials. This page shows the digest next to each token for that reason.
Unlike passwords, a fast hash is appropriate here. Password hashing must be slow because people choose guessable passwords; a 256-bit random token has no dictionary to attack, so SHA-256 is both sufficient and quick enough to run on every request. Compare digests in constant time so response timing does not leak how many leading characters matched.
Lifetimes, rotation, and where each token lives
The pair exists to limit exposure. Access tokens are sent on every request and so are the most likely to leak, which is why they are short-lived, typically five to sixty minutes. The refresh token is sent only to the token endpoint, lives for days or months, and is the credential worth stealing, so it should be stored more carefully than the access token.
The OAuth 2.0 security best current practice recommends refresh token rotation: each refresh issues a new refresh token and invalidates the old one. If an old token is presented again, that is evidence of theft and the whole family should be revoked. Sender-constrained tokens, using DPoP or mutual TLS, go further by binding a token to a specific client key.
Step by step
How to use Token Generator
- Choose the entropy. 256 bits is a good default; 128 bits is the practical minimum for a bearer credential.
- Pick Base64URL for the shortest URL- and header-safe string, or hexadecimal when a system only accepts 0-9 and a-f.
- Set prefixes such as at_ and rt_ so a leaked token is identifiable in logs and by secret scanners.
- Set the two lifetimes, then press Generate token pair and copy the values into your fixture, secret manager, or seeded database row.
- Store the SHA-256 digest shown beneath each token in your database, and keep the plaintext only where the client needs it.
Tokens are generated with crypto.getRandomValues and hashed with the Web Crypto API, entirely in your browser. Nothing is sent to a server, logged, or kept after you leave the page. For the same reason, no token is generated during server rendering: every visitor gets values created on their own machine.
Troubleshooting
Common mistakes and how to fix them
- Deriving a token from a user id, an email, a counter, or a timestamp.
- Any structure is a foothold for guessing. Draw the bytes from a cryptographic random source and keep the identifier in a database column instead.
- Storing tokens in the database in plaintext.
- Store a SHA-256 digest and compare digests. A leaked table then yields nothing an attacker can present.
- Giving the access token a long lifetime to avoid refresh handling.
- That removes the only mitigation for a leaked bearer token. Keep it short and implement the refresh flow properly.
- Putting a token in a URL query string.
- URLs land in server logs, browser history, and Referer headers. Send tokens in the Authorization header.
- Reusing the same refresh token indefinitely.
- Rotate on every use and revoke the family when an already-used token reappears; that reuse is the clearest signal of theft.