Stop pasting your JWTs into random websites to decode them
You've got a JWT and you need to see what's inside it — which user it's for, what scopes it carries, when it expires. The quick move is to search "jwt decoder," grab the first result, and paste your token in. Don't. A JWT is often a live credential, and decoding one is so simple you never need to hand it to a stranger's server. Here's how it actually works. A JWT is just three Base64 strings A…
You possess a JSON Web Token (JWT) and wish to examine its contents, such as the user it's intended for, its associated scopes, and expiration date. The instinctual response might be to search for a "jwt decoder," click the first result, and copy your token into it. However, this is not recommended. JWTs often serve as live credentials, and decoding one is an effortless process that doesn't necessitate sharing the token with the server of someone else.
A JWT is composed of three Base64-encoded sections, separated by dots: the header, payload, and signature. The header specifies how the token is signed (e.g., HS256). The payload contains claims, which are the actual data (user id, scopes, expiry). Lastly, the signature is a cryptographic seal confirming the token hasn't been altered. The first two sections are not encrypted; they're merely Base64URL-encoded, which isn't about secrecy.
You can decode a JWT yourself using the browser's console. Here's a simple JavaScript function to do this:
function decodeJwt (token) {
const part = (seg) =>
JSON.parse(decodeURIComponent(atob(seg.replace(/-/g, '_').replace(/_/g, '/')).split('.').map(c => '%' + c.charCodeAt(0).toString(16).padStart(2, '0')).join('')))
const [header, payload] = token.split('.')
return { header: part(header), payload: part(payload) }
}
decodeJwt(myToken); // { header: { alg: 'HS256', typ: 'JWT' }, payload: { sub: '1234567890', name: 'Jane Doe', exp: 1716242622 } }
This decoding process doesn't verify the token's authenticity. Anyone can decode a JWT, but this doesn't prove it's real. The signature, not the decoding, confirms authenticity. To verify a token, you need the secret or public key it was signed with. For example, HS256 uses HMAC with SHA-256. This means you can decode a JWT to see its contents, but you can't trust it without verifying its signature.
Never trust an unverified JWT, even if the payload seems valid, on a server-side just because it looks right. The payload is not secret. Anyone who possesses the token can read every claim within it. Hence, avoid putting anything sensitive—such as passwords or internal flags—inside a JWT payload.
Converting the expiry timestamp into a readable date can also be tricky. The 'exp' claim, for example, represents a Unix timestamp. '1716242622' means nothing intuitively—convert it to a date to understand if the token is still valid.
While it might be tempting to use random decoder sites, these are not advisable. A live JWT is a bearer token, akin to a password until it expires. Many online decoders send the data you paste to their server, where it could potentially be logged. If that token is still valid, you've essentially given someone a working session. Therefore, it's better to decode the token locally.
There are tools available that decode the header, payload, and claims entirely in your browser, convert the expiry to a readable date, and even flag whether the token is still valid, without sending any data to a server. One such tool is ToolNimbus JWT Decoder. You can also open your network tab while using it to ensure nothing gets sent.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.