JSON Web Token (JWT) Implementation
jsonwebtoken is a robust implementation of JSON Web Tokens (JWT) for Node.js, supporting both symmetric and asymmetric algorithms. The current stable version is 9.0.3. Maintained by Auth0, the library receives regular updates, as indicated by migration notes for recent major versions.
Common errors
-
TokenExpiredError: jwt expired
cause The JWT has exceeded its 'exp' (expiration time) claim.fixIssue a new token with an updated expiration time, or refresh the token if using a refresh token mechanism. -
JsonWebTokenError: invalid signature
cause The token's signature does not match the computed signature, likely due to a tampered token or an incorrect secret/public key used for verification.fixEnsure the same secret or public key (for asymmetric algorithms) that was used to sign the token is used to verify it. Check for any encoding issues with the key. -
JsonWebTokenError: jwt malformed
cause The provided string is not a valid JWT format (e.g., missing segments, incorrect base64 encoding).fixVerify that the token string is complete, correctly encoded, and matches the 'header.payload.signature' structure of a JWT. -
NotBeforeError: jwt not active
cause The token's 'nbf' (not before) claim indicates it should not be accepted yet.fixWait until the 'nbf' time has passed before attempting to use or verify the token. Ensure the system clocks of the issuing and verifying servers are synchronized. -
JsonWebTokenError: secret or public key must be provided
cause The `secretOrPrivateKey` parameter was omitted or was an empty/invalid value during signing or verification.fixProvide a valid string, buffer, or KeyObject for `secretOrPrivateKey` during both signing and verification operations. For private keys with passphrases, use `{ key, passphrase }`.
Warnings
- gotcha Claims like `exp` (expiration time) are only set by the `sign` function if the `payload` parameter is an object literal. If you pass a buffer or string, these claims will not be added or validated.
- breaking When signing with RSA algorithms, private keys with a modulus length shorter than 2048 bits will be rejected by default, resulting in an error.
- gotcha When `expiresIn` or `notBefore` options are provided as a string without a time unit (e.g., `'120'`), the value is interpreted as milliseconds, not seconds, leading to unexpectedly short token lifespans.
- gotcha There are no default values for common JWT claims such as `expiresIn`, `notBefore`, `audience`, `subject`, and `issuer`. If these are not explicitly provided, they will be omitted from the token.
- gotcha The `mutatePayload: true` option directly modifies the original `payload` object passed to `jwt.sign` by adding or overwriting claims (like `iat`, `exp`). This can cause unexpected side effects if the original payload object is reused.
Install
-
npm install jsonwebtoken -
yarn add jsonwebtoken -
pnpm add jsonwebtoken
Imports
- sign
const sign = require('jsonwebtoken').sign;import { sign } from 'jsonwebtoken';
Quickstart
import { sign } from 'jsonwebtoken';
const payload = {
userId: 'user123',
email: 'test@example.com'
};
const secret = process.env.JWT_SECRET ?? 'your-very-strong-secret'; // Use a strong, secure secret in production
try {
// Synchronous signing example
const token = sign(payload, secret, { expiresIn: '1h' });
console.log('Signed JWT:', token);
// Asynchronous signing example
sign(payload, secret, { expiresIn: '1h' }, (err, asyncToken) => {
if (err) {
console.error('Async signing error:', err);
return;
}
console.log('Signed JWT (async):', asyncToken);
});
} catch (error) {
console.error('Error signing token:', error);
}