0
# jsonwebtoken
1
2
A comprehensive JSON Web Token (JWT) implementation for Node.js providing secure token creation, verification, and decoding with support for both symmetric (HMAC) and asymmetric (RSA, ECDSA) cryptographic algorithms.
3
4
## Package Information
5
6
- **Package Name**: jsonwebtoken
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install jsonwebtoken`
10
11
## Core Imports
12
13
```javascript
14
const jwt = require('jsonwebtoken');
15
const { sign, verify, decode, JsonWebTokenError, TokenExpiredError, NotBeforeError } = require('jsonwebtoken');
16
```
17
18
For ES modules:
19
20
```javascript
21
import jwt from 'jsonwebtoken';
22
import { sign, verify, decode, JsonWebTokenError, TokenExpiredError, NotBeforeError } from 'jsonwebtoken';
23
```
24
25
## Basic Usage
26
27
```javascript
28
const jwt = require('jsonwebtoken');
29
30
// Sign a token with HMAC
31
const token = jwt.sign({ userId: 123, username: 'alice' }, 'your-secret-key', {
32
expiresIn: '1h'
33
});
34
35
// Verify a token
36
try {
37
const decoded = jwt.verify(token, 'your-secret-key');
38
console.log(decoded); // { userId: 123, username: 'alice', iat: ..., exp: ... }
39
} catch (err) {
40
if (err instanceof jwt.TokenExpiredError) {
41
console.log('Token expired');
42
} else {
43
console.log('Invalid token');
44
}
45
}
46
47
// Decode without verification (unsafe for untrusted tokens)
48
const payload = jwt.decode(token);
49
```
50
51
## Architecture
52
53
The jsonwebtoken library is built around three core operations:
54
55
- **Token Signing**: Creates JWT tokens with configurable claims and cryptographic algorithms
56
- **Token Verification**: Validates JWT tokens with security checks for timing, audience, issuer, and signature
57
- **Token Decoding**: Extracts payload data without cryptographic verification (for trusted contexts only)
58
- **Error Handling**: Specialized error classes for different failure modes (expiration, malformation, invalid signature)
59
60
The library supports all standard JWT algorithms including HMAC (HS256/384/512), RSA (RS256/384/512, PS256/384/512), and ECDSA (ES256/384/512).
61
62
## Capabilities
63
64
### Token Signing
65
66
Creates and signs JWT tokens with configurable options and claims.
67
68
```javascript { .api }
69
/**
70
* Signs a JWT token with the provided payload and secret/key
71
* @param payload - Object literal, buffer, or string representing valid JSON
72
* @param secretOrPrivateKey - Secret string, buffer, object, or KeyObject for signing
73
* @param options - Optional signing configuration
74
* @param callback - Optional callback for asynchronous operation
75
* @returns JWT string (sync) or calls callback with JWT (async)
76
*/
77
function sign(payload: any, secretOrPrivateKey: string | Buffer | object | KeyObject, options?: SignOptions, callback?: SignCallback): string;
78
79
interface SignOptions {
80
algorithm?: Algorithm;
81
expiresIn?: string | number;
82
notBefore?: string | number;
83
audience?: string | string[];
84
issuer?: string;
85
jwtid?: string;
86
subject?: string;
87
noTimestamp?: boolean;
88
header?: object;
89
keyid?: string;
90
mutatePayload?: boolean;
91
allowInsecureKeySizes?: boolean;
92
allowInvalidAsymmetricKeyTypes?: boolean;
93
encoding?: string;
94
}
95
96
type Algorithm =
97
| 'HS256' | 'HS384' | 'HS512'
98
| 'RS256' | 'RS384' | 'RS512'
99
| 'PS256' | 'PS384' | 'PS512'
100
| 'ES256' | 'ES384' | 'ES512'
101
| 'none';
102
103
type SignCallback = (err: Error | null, token?: string) => void;
104
```
105
106
**Usage Examples:**
107
108
```javascript
109
// Synchronous signing with HMAC
110
const token = jwt.sign({ foo: 'bar' }, 'secret', { expiresIn: '1h' });
111
112
// Asynchronous signing
113
jwt.sign({ foo: 'bar' }, 'secret', { expiresIn: '1h' }, (err, token) => {
114
if (err) throw err;
115
console.log(token);
116
});
117
118
// RSA signing
119
const fs = require('fs');
120
const privateKey = fs.readFileSync('private.key');
121
const token = jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256' });
122
123
// Custom claims
124
const token = jwt.sign(
125
{ userId: 123 },
126
'secret',
127
{
128
expiresIn: '24h',
129
audience: 'my-app',
130
issuer: 'my-service',
131
subject: 'user-auth'
132
}
133
);
134
```
135
136
### Token Verification
137
138
Verifies JWT tokens with comprehensive security validation.
139
140
```javascript { .api }
141
/**
142
* Verifies a JWT token and returns the decoded payload
143
* @param token - JWT string to verify
144
* @param secretOrPublicKey - Secret/key for verification or callback function
145
* @param options - Optional verification configuration
146
* @param callback - Optional callback for asynchronous operation
147
* @returns Decoded payload (sync) or calls callback with payload (async)
148
*/
149
function verify(token: string, secretOrPublicKey: string | Buffer | KeyObject | GetPublicKeyCallback, options?: VerifyOptions, callback?: VerifyCallback): any;
150
151
interface VerifyOptions {
152
algorithms?: Algorithm[];
153
audience?: string | RegExp | (string | RegExp)[];
154
complete?: boolean;
155
issuer?: string | string[];
156
jwtid?: string;
157
ignoreExpiration?: boolean;
158
ignoreNotBefore?: boolean;
159
subject?: string;
160
clockTolerance?: number;
161
maxAge?: string | number;
162
clockTimestamp?: number;
163
nonce?: string;
164
allowInvalidAsymmetricKeyTypes?: boolean;
165
}
166
167
type GetPublicKeyCallback = (header: JwtHeader, callback: (err: any, key?: string | Buffer | KeyObject) => void) => void;
168
type VerifyCallback = (err: Error | null, payload?: any) => void;
169
170
interface JwtHeader {
171
alg: Algorithm;
172
typ?: string;
173
kid?: string;
174
}
175
```
176
177
**Usage Examples:**
178
179
```javascript
180
// Basic verification
181
const decoded = jwt.verify(token, 'secret');
182
183
// Async verification with error handling
184
jwt.verify(token, 'secret', (err, decoded) => {
185
if (err) {
186
if (err instanceof jwt.TokenExpiredError) {
187
console.log('Token expired at:', err.expiredAt);
188
} else if (err instanceof jwt.NotBeforeError) {
189
console.log('Token not active until:', err.date);
190
} else {
191
console.log('Token invalid:', err.message);
192
}
193
} else {
194
console.log('Valid token:', decoded);
195
}
196
});
197
198
// Verification with audience check
199
const decoded = jwt.verify(token, 'secret', {
200
audience: 'my-app',
201
issuer: 'my-service'
202
});
203
204
// Dynamic key resolution
205
function getKey(header, callback) {
206
// Fetch key based on header.kid
207
const key = getPublicKeyFromSomewhere(header.kid);
208
callback(null, key);
209
}
210
211
jwt.verify(token, getKey, (err, decoded) => {
212
console.log(decoded);
213
});
214
215
// Complete token information
216
const result = jwt.verify(token, 'secret', { complete: true });
217
// result = { header: {...}, payload: {...}, signature: "..." }
218
```
219
220
### Token Decoding
221
222
Decodes JWT tokens without cryptographic verification.
223
224
```javascript { .api }
225
/**
226
* Decodes a JWT token without verifying the signature (unsafe for untrusted tokens)
227
* @param token - JWT string to decode
228
* @param options - Optional decoding configuration
229
* @returns Decoded payload object or null if invalid
230
*/
231
function decode(token: string, options?: DecodeOptions): any | null;
232
233
interface DecodeOptions {
234
complete?: boolean;
235
json?: boolean;
236
}
237
```
238
239
**Usage Examples:**
240
241
```javascript
242
// Basic decoding
243
const payload = jwt.decode(token);
244
245
// Complete token structure
246
const decoded = jwt.decode(token, { complete: true });
247
// decoded = { header: {...}, payload: {...}, signature: "..." }
248
249
// Force JSON parsing
250
const payload = jwt.decode(token, { json: true });
251
```
252
253
### Error Handling
254
255
Specialized error classes for different JWT validation failures.
256
257
```javascript { .api }
258
/**
259
* Base error class for JWT-related errors
260
*/
261
class JsonWebTokenError extends Error {
262
name: 'JsonWebTokenError';
263
message: string;
264
inner?: Error;
265
}
266
267
/**
268
* Error thrown when a token has expired
269
*/
270
class TokenExpiredError extends JsonWebTokenError {
271
name: 'TokenExpiredError';
272
message: 'jwt expired';
273
expiredAt: Date;
274
}
275
276
/**
277
* Error thrown when a token is not yet active (nbf claim)
278
*/
279
class NotBeforeError extends JsonWebTokenError {
280
name: 'NotBeforeError';
281
message: 'jwt not active';
282
date: Date;
283
}
284
```
285
286
**Common Error Messages:**
287
288
- `JsonWebTokenError`: 'invalid token', 'jwt malformed', 'jwt signature is required', 'invalid signature'
289
- `JsonWebTokenError`: 'jwt audience invalid', 'jwt issuer invalid', 'jwt id invalid', 'jwt subject invalid'
290
- `TokenExpiredError`: 'jwt expired'
291
- `NotBeforeError`: 'jwt not active'
292
293
## Types
294
295
```javascript { .api }
296
// Supported cryptographic algorithms
297
type Algorithm =
298
| 'HS256' | 'HS384' | 'HS512' // HMAC with SHA
299
| 'RS256' | 'RS384' | 'RS512' // RSASSA-PKCS1-v1_5 with SHA
300
| 'PS256' | 'PS384' | 'PS512' // RSASSA-PSS with SHA (Node.js 6.12+ or 8+)
301
| 'ES256' | 'ES384' | 'ES512' // ECDSA with SHA
302
| 'none'; // No signature
303
304
// Standard JWT header structure
305
interface JwtHeader {
306
alg: Algorithm;
307
typ?: 'JWT';
308
kid?: string; // Key ID
309
}
310
311
// Complete JWT structure when using decode({ complete: true })
312
interface CompleteJwt {
313
header: JwtHeader;
314
payload: any;
315
signature: string;
316
}
317
318
// Validation result when using verify({ complete: true })
319
interface CompleteVerifyResult {
320
header: JwtHeader;
321
payload: any;
322
signature: string;
323
}
324
```
325
326
## Security Considerations
327
328
### Key Requirements
329
330
- **HMAC (HS256/384/512)**: Requires symmetric secret key (string, Buffer, or KeyObject)
331
- **RSA (RS/PS algorithms)**: Requires minimum 2048-bit modulus (configurable with `allowInsecureKeySizes`)
332
- **ECDSA (ES algorithms)**: Requires appropriate elliptic curve (P-256, P-384, P-521)
333
334
### Algorithm Security
335
336
- Default algorithm selection based on key type prevents algorithm confusion attacks
337
- Explicit algorithm specification recommended for production use
338
- `none` algorithm requires explicit inclusion in `algorithms` array for verification
339
340
### Time-based Validation
341
342
- Automatic validation of `exp` (expiration), `nbf` (not before), and `iat` (issued at) claims
343
- Configurable clock tolerance for distributed systems
344
- `maxAge` option for additional age-based validation
345
346
### Best Practices
347
348
```javascript
349
// Specify allowed algorithms explicitly
350
const decoded = jwt.verify(token, publicKey, {
351
algorithms: ['RS256'],
352
audience: 'my-app',
353
issuer: 'trusted-issuer'
354
});
355
356
// Use asymmetric algorithms for distributed systems
357
const token = jwt.sign(payload, privateKey, {
358
algorithm: 'RS256',
359
expiresIn: '15m',
360
audience: 'api-client',
361
issuer: 'auth-service'
362
});
363
364
// Handle errors appropriately
365
try {
366
const decoded = jwt.verify(token, secret);
367
// Process valid token
368
} catch (err) {
369
if (err instanceof jwt.TokenExpiredError) {
370
// Handle expired token (maybe refresh)
371
} else if (err instanceof jwt.JsonWebTokenError) {
372
// Handle invalid token
373
}
374
}
375
```