DEV Community

Muhammad Ali Khan
Muhammad Ali Khan

Posted on

Decode a JWT Without Sending It to a Server

A JSON Web Token (JWT) looks like random text, but it is just three Base64URL-encoded parts joined by dots: header, payload and signature. Decoding the first two takes a few lines of code, so you never need to paste a real token into a random website.

Why not paste tokens into online tools?

A live token can grant access to an account or API. If a tool sends it to a server, you have shared a credential. Decode locally, in the browser or your terminal, so the token never leaves your machine.

Decode in the browser or Node

function decodeJwt(token) {
  const [header, payload] = token.split('.').slice(0, 2).map((part) => {
    const b64 = part.replace(/-/g, '+').replace(/_/g, '/');
    const padded = b64.padEnd(b64.length + (4 - (b64.length % 4)) % 4, '=');
    const json = decodeURIComponent(
      atob(padded)
        .split('')
        .map((c) => '%' + c.charCodeAt(0).toString(16).padStart(2, '0'))
        .join('')
    );
    return JSON.parse(json);
  });
  return { header, payload };
}

const { payload } = decodeJwt(token);
console.log(payload.exp && new Date(payload.exp * 1000));
Enter fullscreen mode Exit fullscreen mode

The Base64URL step matters: JWTs use - and _ instead of + and /, and drop the = padding, so plain atob fails on some tokens without the fix above.

Decode in the terminal

echo "$TOKEN" | cut -d. -f2 | tr '_-' '/+' | base64 -d 2>/dev/null | jq .
Enter fullscreen mode Exit fullscreen mode

What decoding does not do

Decoding is not verifying. Anyone can read the payload, and anyone can write a fake one. Only checking the signature with the right secret or public key proves the token is genuine, and that must happen on your server. Never put secrets in a payload.

Handy claims to check

  • exp: expiry time (Unix seconds). Expired tokens are the most common cause of surprise 401 errors.
  • iat: when it was issued.
  • aud and iss: who the token is for and who issued it.

A no-upload option

If you would rather not write code, the JWT Decoder on UtilGenie is one option that decodes in the browser. The snippets above work just as well.

Top comments (0)