Overview of jsonwebtoken
masterdraft-ietf-oauth-json-web-token-08 and utilizes node-jws internally.repository·master·Indexed 12 days ago
https://github.com/auth0/node-jsonwebtokenA Node.js implementation of the JSON Web Token (JWT) standard (RFC 7519) for creating, signing, and verifying tokens. Version 9.0.3 supports symmetric and asymmetric algorithms including HMAC, RSA, and ECDSA. Provides a core API consisting of jwt.sign() for token creation, jwt.verify() for signature and claim validation, and jwt.decode() for extracting payloads without verification.
draft-ietf-oauth-json-web-token-08 and utilizes node-jws internally.The exp (expiration) claim follows the JWT standard and is represented as a NumericDate.
NumericDate Definition: A JSON numeric value representing the number of seconds from 1970-01-01T00:00:00Z UTC until the specified UTC date/time. This is equivalent to 'Seconds Since the Epoch'.
When using jwt.sign(), you can set this manually in the payload or use the expiresIn option. If you use expiresIn, the library calculates the exp for you based on the current time.
// Manual NumericDate calculation
jwt.sign({
exp: Math.floor(Date.now() / 1000) + (60 * 60), // 1 hour from now
data: 'foobar'
}, 'secret');
// Using expiresIn option (recommended)
jwt.sign({
data: 'foobar'
}, 'secret', { expiresIn: '1h' });To use this library in your project, install it using npm:
$ npm install jsonwebtokenUse jwt.decode() to extract the payload and header from a JWT without verifying the signature.
Warning: This method does not check if the token is valid or has been tampered with. Do not use this for untrusted messages; use jwt.verify() instead for security-sensitive operations.
Options:
json: Force JSON.parse on the payload even if the header doesn't contain "typ":"JWT".complete: If true, returns an object containing both the payload and the header.var jwt = require('jsonwebtoken');
// Get the decoded payload ignoring signature
var decoded = jwt.decode(token);
// Get the decoded payload and header
var decoded = jwt.decode(token, {complete: true});
console.log(decoded.header);
console.log(decoded.payload);Use jwt.sign() to create a new JWT. It can be used synchronously (returns the token string) or asynchronously (if a callback is provided).
Payload Types:
exp or sub directly in the payload. If you use options.expiresIn, the library will automatically set the exp claim.exp or other claims will not be set automatically if the payload is not an object literal.Key Options:
algorithm: The signing algorithm (default: HS256).expiresIn: Time span for token validity (e.g., 60, '2 days', '10h'). Numeric values are treated as seconds. Strings use vercel/ms logic (e.g., '120' defaults to 120ms unless units are provided).notBefore: Time span for the nbf claim.mutatePayload: If true, the function modifies the original payload object directly.allowInsecureKeySizes: If true, allows RSA private keys with a modulus below 2048.Important Note on Claims:
You can provide claims like exp, nbf, aud, sub, and iss directly in the payload object, or via options. You cannot include the same claim in both places.
var jwt = require('jsonwebtoken');
// Synchronous Sign with default (HMAC SHA256)
var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
// Synchronous Sign with RSA SHA256
var privateKey = fs.readFileSync('private.key');
var token = jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256' });
// Sign asynchronously
jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256' }, function(err, token) {
console.log(token);
});
// Signing a token with 1 hour of expiration using expiresIn
jwt.sign({
data: 'foobar'
}, 'secret', { expiresIn: '1h' });Use jwt.verify() to validate a token's signature and claims.
Key Options:
algorithms: A list of allowed algorithms (e.g., ['HS256', 'HS384']). If not specified, defaults are chosen based on the key type (secret $\rightarrow$ HMAC, rsa $\rightarrow$ RSA, ec $\rightarrow$ ECDSA).audience: Validates the aud claim against a string, regex, or array of strings/regex.issuer: Validates the iss claim against a string or array of strings.clockTolerance: Number of seconds to tolerate for nbf and exp checks to account for clock drift.maxAge: Maximum allowed age for tokens (e.g., '2 days').ignoreExpiration: If true, skips exp validation.complete: If true, returns an object containing { payload, header, signature } instead of just the payload.Security Warning: When the token comes from an untrusted source, treat the returned payload as untrusted user input. Sanitize it before use.
var jwt = require('jsonwebtoken');
var cert = fs.readFileSync('public.pem');
// Verify a token symmetric - synchronous
var decoded = jwt.verify(token, 'shhhhh');
// Verify a token asymmetric
jwt.verify(token, cert, function(err, decoded) {
console.log(decoded.foo);
});
// Verify with specific audience and issuer
jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer' }, function(err, decoded) {
// if mismatch, err == invalid audience/issuer
});
// Verify using a getKey callback (e.g., for JWKS)
function getKey(header, callback){
client.getSigningKey(header.kid, function(err, key) {
var signingKey = key.publicKey || key.rsaPublicKey;
callback(null, signingKey);
});
}
jwt.verify(token, getKey, options, function(err, decoded) {
console.log(decoded.foo);
});The JsonWebTokenError is thrown for several specific validation failures. The message property will contain one of the following strings:
invalid token: The header or payload could not be parsed.jwt malformed: The token does not have three components (delimited by a .).jwt signature is required: No signature was provided.invalid signature: The signature does not match.jwt audience invalid. expected: [OPTIONS AUDIENCE]: The aud claim does not match the provided options.jwt issuer invalid. expected: [OPTIONS ISSUER]: The iss claim does not match the provided options.jwt id invalid. expected: [OPTIONS JWT ID]: The jti claim does not match the provided options.jwt subject invalid. expected: [OPTIONS SUBJECT]: The sub claim does not match the provided options.The library supports a wide range of digital signature and MAC algorithms. When signing or verifying, you can specify the algorithm in the options object.
| alg Parameter Value | Description |
|---|---|
HS256 | HMAC using SHA-256 |
HS384 | HMAC using SHA-384 |
HS512 | HMAC using SHA-512 |
RS256 | RSASSA-PKCS1-v1_5 using SHA-256 |
RS384 | RSASSA-PKCS1-v1_5 using SHA-384 |
RS512 | RSASSA-PKCS1-v1_5 using SHA-512 |
PS256 | RSASSA-PSS using SHA-256 (Node ^6.12.0 or >=8.0.0) |
PS384 | RSASSA-PSS using SHA-384 (Node ^6.12.0 or >=8.0.0) |
PS512 | RSASSA-PSS using SHA-512 (Node ^6.12.0 or >=8.0.0) |
ES256 | ECDSA using P-256 curve and SHA-256 |
ES384 | ECDSA using P-384 curve and SHA-384 |
ES512 | ECDSA using P-521 curve and SHA-512 |
none | No digital signature or MAC value included |
When using the callback version of jwt.verify(), the first argument err contains error details if verification fails. There are three primary error types you should handle:
exp claim in the token is in the past. The error object includes expiredAt.nbf (not before) claim. The error object includes date.aud (audience), iss (issuer), jti (JWT ID), or sub (subject).Always check for the existence of err in your callback before processing the decoded payload.
// Example: Handling a TokenExpiredError
jwt.verify(token, 'shhhhh', function(err, decoded) {
if (err) {
if (err.name === 'TokenExpiredError') {
console.log('Token expired at:', err.expiredAt);
} else if (err.name === 'JsonWebTokenError') {
console.log('Invalid token:', err.message);
}
}
});The TokenExpiredError is thrown by jwt.verify() when a token's exp (expiration) claim indicates that the token is no longer valid. This error is a subclass of JsonWebTokenError.
When catching this error, you can access the expiredAt property to determine exactly when the token expired.
const jwt = require('jsonwebtoken');
try {
const decoded = jwt.verify(token, secret);
} catch (err) {
if (err.name === 'TokenExpiredError') {
console.error(`Token expired at: ${err.expiredAt}`);
} else {
console.error('Verification failed:', err.message);
}
}NotBeforeError is thrown by jwt.verify() when a token contains an nbf (not before) claim that is set to a time in the future. This means the token is not yet valid for use. This error inherits from JsonWebTokenError and includes a date property representing the nbf timestamp from the token.When using verify(), the library may throw or return specific error types that you should catch to handle different failure scenarios:
JsonWebTokenError: A general error for invalid tokens (e.g., malformed signatures).TokenExpiredError: Thrown when the token's exp claim indicates it has expired.NotBeforeError: Thrown when the token's nbf (not before) claim indicates it is not yet valid.const jwt = require('jsonwebtoken');
try {
const decoded = jwt.verify(token, secret);
} catch (err) {
if (err instanceof jwt.TokenExpiredError) {
// Handle expired token
} else if (err instanceof jwt.JsonWebTokenError) {
// Handle invalid token
} else if (err instanceof jwt.NotBeforeError) {
// Handle token not yet active
}
}