JWT Decoder CLI
A Node CLI that decodes a JSON Web Token into its header and payload JSON without verifying the signature, and warns loudly that it does not verify.
Project
node-jwt-decode
Entry point: jwt-decode.mjs
Install
node --versionRun
node jwt-decode.mjs <token>Test
node --test jwt-decode.test.mjsExpected output
Prints the decoded header and payload JSON and a clear notice that the signature was not verified.Dependencies
- node >=20
What it does
Decodes the header and payload of a JWT for inspection, which is the common need when debugging an authentication flow. It deliberately does not verify the signature.
function decodeSegment(segment) {
return JSON.parse(Buffer.from(segment, 'base64url').toString('utf8'));
}
const token = process.argv[2];
if (!token) { console.error('usage: jwt-decode <token>'); process.exit(1); }
const parts = token.split('.');
if (parts.length !== 3) { console.error('not a JWT: expected 3 segments'); process.exit(1); }
try {
const header = decodeSegment(parts[0]);
const payload = decodeSegment(parts[1]);
console.log('header ' + JSON.stringify(header));
console.log('payload ' + JSON.stringify(payload));
console.error('warning: signature NOT verified - do not trust this payload');
} catch (err) {
console.error('decode failed: ' + err.message);
process.exit(1);
}
Because decoding without verification is a security-sensitive convenience, the tool prints an explicit warning so nobody mistakes inspection for validation.
Run and verify
node jwt-decode.mjs eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyLTEifQ.x
Pass any three-segment token; the signature segment is ignored, so an expired or bogus signature still decodes.
Expected Output
The sample token decodes to an HS256 header and a payload with a subject claim, plus a warning on stderr. The output is:
header {"alg":"HS256"}
payload {"sub":"user-1"}
warning: signature NOT verified - do not trust this payload
A token with fewer or more than three segments is rejected before any decoding, and malformed base64 fails with a decode error.
Limitations
It never verifies signatures or checks expiry; use it only for inspection, and never make an authorisation decision from its output.