API Reference verify
API Reference: jwt.verify()
Verifies a JSON Web Token string and returns the decoded payload if the signature is valid.
Syntax
jwt.verify(token: string, secretOrPublicKey: Secret | PublicKey | GetPublicKeyOrSecret, options?: VerifyOptions): Promise<JwtPayload | string>
Parameters
token
The JWT string to verify.
secretOrPublicKey
The key used to verify the token signature:
- String - UTF-8 encoded secret for HMAC algorithms
- Buffer - Secret for HMAC algorithms
- KeyObject - Public key for RSA/ECDSA algorithms
- Function - Async function that returns the key (for dynamic key resolution)
options (optional)
Configuration object with the following properties:
Verification Options
| Option | Type | Description |
|---|---|---|
algorithms |
string[] |
List of allowed algorithms |
audience |
string | RegExp | (string|RegExp)[] |
Expected audience |
complete |
boolean |
Return an object with decoded header and payload |
issuer |
string | string[] |
Expected issuer |
jwtid |
string |
Expected JWT ID |
ignoreExpiration |
boolean |
Skip expiration check |
ignoreNotBefore |
boolean |
Skip not-before check |
subject |
string |
Expected subject |
clockTolerance |
number |
Clock tolerance in seconds |
maxAge |
string | number |
Maximum token age |
clockTimestamp |
number |
Time to use as current time (seconds) |
nonce |
string |
Expected nonce value |
allowInvalidAsymmetricKeyTypes |
boolean |
Allow mismatched key types |
Return Value
Returns a Promise that resolves to:
- Decoded payload (default) - The JWT payload as an object or string
-
Complete JWT (when
complete: true) - Object with{ header, payload, signature }
Examples
Basic Verification
const jwt = require('jsonwebtoken'); try { const decoded = await jwt.verify(token, 'secret'); console.log(decoded); // { userId: 123, iat: 1516239022 } } catch (err) { console.error('Invalid token'); }
RSA Public Key Verification
const fs = require('fs'); const publicKey = fs.readFileSync('public.pem'); try { const decoded = await jwt.verify(token, publicKey); console.log(decoded); } catch (err) { console.error('Invalid signature'); }
Algorithm Validation
try { // Only allow specific algorithms const decoded = await jwt.verify(token, publicKey, { algorithms: ['RS256', 'RS384'] }); } catch (err) { if (err.message.includes('invalid signature')) { console.error('Algorithm mismatch'); } }
Audience Validation
// Single audience const decoded = await jwt.verify(token, secret, { audience: 'urn:my-app' }); // Multiple audiences const decoded = await jwt.verify(token, secret, { audience: ['urn:my-app', 'urn:other-app'] }); // Regex pattern const decoded = await jwt.verify(token, secret, { audience: /^urn:app:.+$/ });
Complete Token Information
const complete = await jwt.verify(token, secret, { complete: true }); console.log(complete.header); // { alg: 'HS256', typ: 'JWT' } console.log(complete.payload); // { userId: 123, ... } console.log(complete.signature); // 'xyz...'
Dynamic Key Resolution
// Function that returns the appropriate key async function getKey(header) { // Fetch key based on kid (key ID) in header const key = await fetchKeyFromDatabase(header.kid); return key; } try { const decoded = await jwt.verify(token, getKey); console.log(decoded); } catch (err) { console.error('Verification failed'); }
Using with jwks-rsa
const jwksClient = require('jwks-rsa'); const client = jwksClient({ jwksUri: 'https://YOUR_DOMAIN/.well-known/jwks.json' }); async function getKey(header) { const key = await client.getSigningKey(header.kid); return key.publicKey || key.rsaPublicKey; } const decoded = await jwt.verify(token, getKey);
Clock Tolerance
Handle small time differences between servers:
const decoded = await jwt.verify(token, secret, { clockTolerance: 60 // 60 seconds tolerance });
Maximum Age
Reject tokens older than specified age:
const decoded = await jwt.verify(token, secret, { maxAge: '2h' // Token must be less than 2 hours old });
TypeScript Usage
import jwt, { JwtPayload, VerifyOptions, GetPublicKeyOrSecret } from 'jsonwebtoken'; interface TokenPayload extends JwtPayload { userId: number; role: string; } const options: VerifyOptions = { algorithms: ['RS256'], audience: 'api.example.com', issuer: 'auth.example.com' }; try { const decoded = await jwt.verify(token, publicKey, options) as TokenPayload; console.log(decoded.userId); // Type-safe access } catch (error) { if (error instanceof jwt.TokenExpiredError) { console.log('Token expired at:', error.expiredAt); } else if (error instanceof jwt.JsonWebTokenError) { console.log('Invalid token:', error.message); } }
Error Handling
The verify method will reject with specific error types:
TokenExpiredError
try { const decoded = await jwt.verify(token, secret); } catch (err) { if (err.name === 'TokenExpiredError') { console.log('Token expired at:', err.expiredAt); } }
JsonWebTokenError
try { const decoded = await jwt.verify(token, secret); } catch (err) { if (err.name === 'JsonWebTokenError') { // Could be: invalid signature, jwt malformed, etc. console.log('JWT Error:', err.message); } }
NotBeforeError
try { const decoded = await jwt.verify(token, secret); } catch (err) { if (err.name === 'NotBeforeError') { console.log('Token not active until:', err.date); } }
Security Considerations
-
Algorithm Validation: Always specify allowed algorithms:
await jwt.verify(token, key, { algorithms: ['RS256'] });
-
Audience Validation: Verify the token is for your application:
await jwt.verify(token, secret, { audience: 'your-app-id' });
-
Issuer Validation: Verify the token issuer:
await jwt.verify(token, secret, { issuer: 'trusted-issuer' });
-
Base64 Secrets: If using base64 encoded secrets:
const secret = Buffer.from(process.env.JWT_SECRET_BASE64, 'base64'); const decoded = await jwt.verify(token, secret);
Common Patterns
Express Middleware
async function authenticateToken(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (!token) { return res.sendStatus(401); } try { const user = await jwt.verify(token, process.env.ACCESS_TOKEN_SECRET); req.user = user; next(); } catch (err) { return res.sendStatus(403); } }
Refresh Token Validation
async function validateRefreshToken(token) { try { const decoded = await jwt.verify(token, process.env.REFRESH_TOKEN_SECRET, { audience: 'refresh', issuer: 'auth-service' }); return decoded; } catch (err) { throw new Error('Invalid refresh token'); } }
Multi-Tenant Validation
async function verifyTenantToken(token, tenantId) { const decoded = await jwt.verify(token, secret, { audience: `tenant:${tenantId}`, issuer: 'multi-tenant-app' }); return decoded; }
See Also
- jwt.sign() - Create tokens
- jwt.decode() - Decode without verification
- Error Reference - Error handling details
- Security & Algorithms - Security best practices