• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..21-May-2021-

lib/H03-May-2022-

LICENSEH A D21-May-20211.1 KiB2217

README.mdH A D21-May-202113.2 KiB338246

package.jsonH A D21-May-20211.1 KiB5251

README.md

1# jsonwebtoken
2
3[![Build Status](https://secure.travis-ci.org/auth0/node-jsonwebtoken.svg?branch=master)](http://travis-ci.org/auth0/node-jsonwebtoken)[![Dependency Status](https://david-dm.org/auth0/node-jsonwebtoken.svg)](https://david-dm.org/auth0/node-jsonwebtoken)
4
5
6An implementation of [JSON Web Tokens](https://tools.ietf.org/html/rfc7519).
7
8This was developed against `draft-ietf-oauth-json-web-token-08`. It makes use of [node-jws](https://github.com/brianloveswords/node-jws)
9
10# Install
11
12```bash
13$ npm install jsonwebtoken
14```
15
16# Migration notes
17
18* [From v7 to v8](https://github.com/auth0/node-jsonwebtoken/wiki/Migration-Notes:-v7-to-v8)
19
20# Usage
21
22### jwt.sign(payload, secretOrPrivateKey, [options, callback])
23
24(Asynchronous) If a callback is supplied, the callback is called with the `err` or the JWT.
25
26(Synchronous) Returns the JsonWebToken as string
27
28`payload` could be an object literal, buffer or string representing valid JSON. *Please note that* `exp` or any other claim is only set if the payload is an object literal. Buffer or string payloads are not checked for JSON validity.
29
30`secretOrPrivateKey` is a string, buffer, or object containing either the secret for HMAC algorithms or the PEM
31encoded private key for RSA and ECDSA. In case of a private key with passphrase an object `{ key, passphrase }` can be used (based on [crypto documentation](https://nodejs.org/api/crypto.html#crypto_sign_sign_private_key_output_format)), in this case be sure you pass the `algorithm` option.
32
33`options`:
34
35* `algorithm` (default: `HS256`)
36* `expiresIn`: expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms). Eg: `60`, `"2 days"`, `"10h"`, `"7d"`. A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default (`"120"` is equal to `"120ms"`).
37* `notBefore`: expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms). Eg: `60`, `"2 days"`, `"10h"`, `"7d"`. A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default (`"120"` is equal to `"120ms"`).
38* `audience`
39* `issuer`
40* `jwtid`
41* `subject`
42* `noTimestamp`
43* `header`
44* `keyid`
45* `mutatePayload`: if true, the sign function will modify the payload object directly. This is useful if you need a raw reference to the payload after claims have been applied to it but before it has been encoded into a token.
46
47If `payload` is not a buffer or a string, it will be coerced into a string using `JSON.stringify`.
48
49There are no default values for `expiresIn`, `notBefore`, `audience`, `subject`, `issuer`. These claims can also be provided in the payload directly with `exp`, `nbf`, `aud`, `sub` and `iss` respectively, but you can't include in both places.
50
51Remember that `exp`, `nbf` and `iat` are **NumericDate**, see related [Token Expiration (exp claim)](#token-expiration-exp-claim)
52
53
54The header can be customized via the `options.header` object.
55
56Generated jwts will include an `iat` (issued at) claim by default unless `noTimestamp` is specified. If `iat` is inserted in the payload, it will be used instead of the real timestamp for calculating other things like `exp` given a timespan in `options.expiresIn`.
57
58Sign with default (HMAC SHA256)
59
60```js
61var jwt = require('jsonwebtoken');
62var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
63```
64
65Sign with RSA SHA256
66```js
67// sign with RSA SHA256
68var cert = fs.readFileSync('private.key');
69var token = jwt.sign({ foo: 'bar' }, cert, { algorithm: 'RS256'});
70```
71
72Sign asynchronously
73```js
74jwt.sign({ foo: 'bar' }, cert, { algorithm: 'RS256' }, function(err, token) {
75  console.log(token);
76});
77```
78
79Backdate a jwt 30 seconds
80```js
81var older_token = jwt.sign({ foo: 'bar', iat: Math.floor(Date.now() / 1000) - 30 }, 'shhhhh');
82```
83
84#### Token Expiration (exp claim)
85
86The standard for JWT defines an `exp` claim for expiration. The expiration is represented as a **NumericDate**:
87
88> A JSON numeric value representing the number of seconds from 1970-01-01T00:00:00Z UTC until the specified UTC date/time, ignoring leap seconds.  This is equivalent to the IEEE Std 1003.1, 2013 Edition [POSIX.1] definition "Seconds Since the Epoch", in which each day is accounted for by exactly 86400 seconds, other than that non-integer values can be represented.  See RFC 3339 [RFC3339] for details regarding date/times in general and UTC in particular.
89
90This means that the `exp` field should contain the number of seconds since the epoch.
91
92Signing a token with 1 hour of expiration:
93
94```javascript
95jwt.sign({
96  exp: Math.floor(Date.now() / 1000) + (60 * 60),
97  data: 'foobar'
98}, 'secret');
99```
100
101Another way to generate a token like this with this library is:
102
103```javascript
104jwt.sign({
105  data: 'foobar'
106}, 'secret', { expiresIn: 60 * 60 });
107
108//or even better:
109
110jwt.sign({
111  data: 'foobar'
112}, 'secret', { expiresIn: '1h' });
113```
114
115### jwt.verify(token, secretOrPublicKey, [options, callback])
116
117(Asynchronous) If a callback is supplied, function acts asynchronously. The callback is called with the decoded payload if the signature is valid and optional expiration, audience, or issuer are valid. If not, it will be called with the error.
118
119(Synchronous) If a callback is not supplied, function acts synchronously. Returns the payload decoded if the signature is valid and optional expiration, audience, or issuer are valid. If not, it will throw the error.
120
121`token` is the JsonWebToken string
122
123`secretOrPublicKey` is a string or buffer containing either the secret for HMAC algorithms, or the PEM
124encoded public key for RSA and ECDSA.
125If `jwt.verify` is called asynchronous, `secretOrPublicKey` can be a function that should fetch the secret or public key. See below for a detailed example
126
127As mentioned in [this comment](https://github.com/auth0/node-jsonwebtoken/issues/208#issuecomment-231861138), there are other libraries that expect base64 encoded secrets (random bytes encoded using base64), if that is your case you can pass `Buffer.from(secret, 'base64')`, by doing this the secret will be decoded using base64 and the token verification will use the original random bytes.
128
129`options`
130
131* `algorithms`: List of strings with the names of the allowed algorithms. For instance, `["HS256", "HS384"]`.
132* `audience`: if you want to check audience (`aud`), provide a value here. The audience can be checked against a string, a regular expression or a list of strings and/or regular expressions. Eg: `"urn:foo"`, `/urn:f[o]{2}/`, `[/urn:f[o]{2}/, "urn:bar"]`
133* `issuer` (optional): string or array of strings of valid values for the `iss` field.
134* `ignoreExpiration`: if `true` do not validate the expiration of the token.
135* `ignoreNotBefore`...
136* `subject`: if you want to check subject (`sub`), provide a value here
137* `clockTolerance`: number of seconds to tolerate when checking the `nbf` and `exp` claims, to deal with small clock differences among different servers
138* `maxAge`: the maximum allowed age for tokens to still be valid. It is expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms). Eg: `1000`, `"2 days"`, `"10h"`, `"7d"`. A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default (`"120"` is equal to `"120ms"`).
139* `clockTimestamp`: the time in seconds that should be used as the current time for all necessary comparisons.
140
141
142```js
143// verify a token symmetric - synchronous
144var decoded = jwt.verify(token, 'shhhhh');
145console.log(decoded.foo) // bar
146
147// verify a token symmetric
148jwt.verify(token, 'shhhhh', function(err, decoded) {
149  console.log(decoded.foo) // bar
150});
151
152// invalid token - synchronous
153try {
154  var decoded = jwt.verify(token, 'wrong-secret');
155} catch(err) {
156  // err
157}
158
159// invalid token
160jwt.verify(token, 'wrong-secret', function(err, decoded) {
161  // err
162  // decoded undefined
163});
164
165// verify a token asymmetric
166var cert = fs.readFileSync('public.pem');  // get public key
167jwt.verify(token, cert, function(err, decoded) {
168  console.log(decoded.foo) // bar
169});
170
171// verify audience
172var cert = fs.readFileSync('public.pem');  // get public key
173jwt.verify(token, cert, { audience: 'urn:foo' }, function(err, decoded) {
174  // if audience mismatch, err == invalid audience
175});
176
177// verify issuer
178var cert = fs.readFileSync('public.pem');  // get public key
179jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer' }, function(err, decoded) {
180  // if issuer mismatch, err == invalid issuer
181});
182
183// verify jwt id
184var cert = fs.readFileSync('public.pem');  // get public key
185jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer', jwtid: 'jwtid' }, function(err, decoded) {
186  // if jwt id mismatch, err == invalid jwt id
187});
188
189// verify subject
190var cert = fs.readFileSync('public.pem');  // get public key
191jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer', jwtid: 'jwtid', subject: 'subject' }, function(err, decoded) {
192  // if subject mismatch, err == invalid subject
193});
194
195// alg mismatch
196var cert = fs.readFileSync('public.pem'); // get public key
197jwt.verify(token, cert, { algorithms: ['RS256'] }, function (err, payload) {
198  // if token alg != RS256,  err == invalid signature
199});
200
201// Verify using getKey callback
202// Example uses https://github.com/auth0/node-jwks-rsa as a way to fetch the keys.
203var jwksClient = require('jwks-rsa');
204var client = jwksClient({
205  jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json'
206});
207function getKey(header, callback){
208  client.getSigningKey(header.kid, function(err, key) {
209    var signingKey = key.publicKey || key.rsaPublicKey;
210    callback(null, signingKey);
211  });
212}
213
214jwt.verify(token, getKey, options, function(err, decoded) {
215  console.log(decoded.foo) // bar
216});
217
218```
219
220### jwt.decode(token [, options])
221
222(Synchronous) Returns the decoded payload without verifying if the signature is valid.
223
224__Warning:__ This will __not__ verify whether the signature is valid. You should __not__ use this for untrusted messages. You most likely want to use `jwt.verify` instead.
225
226`token` is the JsonWebToken string
227
228`options`:
229
230* `json`: force JSON.parse on the payload even if the header doesn't contain `"typ":"JWT"`.
231* `complete`: return an object with the decoded payload and header.
232
233Example
234
235```js
236// get the decoded payload ignoring signature, no secretOrPrivateKey needed
237var decoded = jwt.decode(token);
238
239// get the decoded payload and header
240var decoded = jwt.decode(token, {complete: true});
241console.log(decoded.header);
242console.log(decoded.payload)
243```
244
245## Errors & Codes
246Possible thrown errors during verification.
247Error is the first argument of the verification callback.
248
249### TokenExpiredError
250
251Thrown error if the token is expired.
252
253Error object:
254
255* name: 'TokenExpiredError'
256* message: 'jwt expired'
257* expiredAt: [ExpDate]
258
259```js
260jwt.verify(token, 'shhhhh', function(err, decoded) {
261  if (err) {
262    /*
263      err = {
264        name: 'TokenExpiredError',
265        message: 'jwt expired',
266        expiredAt: 1408621000
267      }
268    */
269  }
270});
271```
272
273### JsonWebTokenError
274Error object:
275
276* name: 'JsonWebTokenError'
277* message:
278  * 'jwt malformed'
279  * 'jwt signature is required'
280  * 'invalid signature'
281  * 'jwt audience invalid. expected: [OPTIONS AUDIENCE]'
282  * 'jwt issuer invalid. expected: [OPTIONS ISSUER]'
283  * 'jwt id invalid. expected: [OPTIONS JWT ID]'
284  * 'jwt subject invalid. expected: [OPTIONS SUBJECT]'
285
286```js
287jwt.verify(token, 'shhhhh', function(err, decoded) {
288  if (err) {
289    /*
290      err = {
291        name: 'JsonWebTokenError',
292        message: 'jwt malformed'
293      }
294    */
295  }
296});
297```
298
299## Algorithms supported
300
301Array of supported algorithms. The following algorithms are currently supported.
302
303alg Parameter Value | Digital Signature or MAC Algorithm
304----------------|----------------------------
305HS256 | HMAC using SHA-256 hash algorithm
306HS384 | HMAC using SHA-384 hash algorithm
307HS512 | HMAC using SHA-512 hash algorithm
308RS256 | RSASSA using SHA-256 hash algorithm
309RS384 | RSASSA using SHA-384 hash algorithm
310RS512 | RSASSA using SHA-512 hash algorithm
311ES256 | ECDSA using P-256 curve and SHA-256 hash algorithm
312ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm
313ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm
314none | No digital signature or MAC value included
315
316## Refreshing JWTs
317
318First of all, we recommend to think carefully if auto-refreshing a JWT will not introduce any vulnerability in your system.
319
320We are not comfortable including this as part of the library, however, you can take a look to [this example](https://gist.github.com/ziluvatar/a3feb505c4c0ec37059054537b38fc48) to show how this could be accomplished.
321Apart from that example there are [an issue](https://github.com/auth0/node-jsonwebtoken/issues/122) and [a pull request](https://github.com/auth0/node-jsonwebtoken/pull/172) to get more knowledge about this topic.
322
323# TODO
324
325* X.509 certificate chain is not checked
326
327## Issue Reporting
328
329If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues.
330
331## Author
332
333[Auth0](https://auth0.com)
334
335## License
336
337This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info.
338