You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					233 lines
				
				6.9 KiB
			
		
		
			
		
	
	
					233 lines
				
				6.9 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								# jsonwebtoken [](http://travis-ci.org/auth0/node-jsonwebtoken)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								An implementation of [JSON Web Tokens](https://tools.ietf.org/html/rfc7519).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This was developed against `draft-ietf-oauth-json-web-token-08`. It makes use of [node-jws](https://github.com/brianloveswords/node-jws)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Install
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```bash
							 | 
						||
| 
								 | 
							
								$ npm install jsonwebtoken
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Usage
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### jwt.sign(payload, secretOrPrivateKey, options)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(Synchronous) Returns the JsonWebToken as string
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`payload` could be an object literal, buffer or string. *Please note that* `exp` is only set if the payload is an object literal.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`secretOrPrivateKey` is a string or buffer containing either the secret for HMAC algorithms, or the PEM
							 | 
						||
| 
								 | 
							
								encoded private key for RSA and ECDSA.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`options`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								* `algorithm` (default: `HS256`)
							 | 
						||
| 
								 | 
							
								* `expiresIn`: expressed in seconds or an string describing a time span [rauchg/ms](https://github.com/rauchg/ms.js). Eg: `60`, `"2 days"`, `"10h"`, `"7d"`
							 | 
						||
| 
								 | 
							
								* `audience`
							 | 
						||
| 
								 | 
							
								* `subject`
							 | 
						||
| 
								 | 
							
								* `issuer`
							 | 
						||
| 
								 | 
							
								* `noTimestamp`
							 | 
						||
| 
								 | 
							
								* `headers`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If `payload` is not a buffer or a string, it will be coerced into a string
							 | 
						||
| 
								 | 
							
								using `JSON.stringify`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If any `expiresIn`, `audience`, `subject`, `issuer` are not provided, there is no default. The jwt generated won't include those properties in the payload.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Additional headers can be provided via the `headers` object.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Generated jwts will include an `iat` claim by default unless `noTimestamp` is specified.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Example
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// sign with default (HMAC SHA256)
							 | 
						||
| 
								 | 
							
								var jwt = require('jsonwebtoken');
							 | 
						||
| 
								 | 
							
								var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// sign with RSA SHA256
							 | 
						||
| 
								 | 
							
								var cert = fs.readFileSync('private.key');  // get private key
							 | 
						||
| 
								 | 
							
								var token = jwt.sign({ foo: 'bar' }, cert, { algorithm: 'RS256'});
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### jwt.verify(token, secretOrPublicKey, [options, callback])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(Asynchronous) If a callback is supplied, function acts asynchronously. Callback passed the payload decoded if the signature (and optionally expiration, audience, issuer) are valid. If not, it will be passed the error.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(Synchronous) If a callback is not supplied, function acts synchronously. Returns the payload decoded if the signature (and optionally expiration, audience, issuer) are valid. If not, it will throw the error.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`token` is the JsonWebToken string
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`secretOrPublicKey` is a string or buffer containing either the secret for HMAC algorithms, or the PEM
							 | 
						||
| 
								 | 
							
								encoded public key for RSA and ECDSA.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`options`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								* `algorithms`: List of strings with the names of the allowed algorithms. For instance, `["HS256", "HS384"]`.
							 | 
						||
| 
								 | 
							
								* `audience`: if you want to check audience (`aud`), provide a value here
							 | 
						||
| 
								 | 
							
								* `issuer`: if you want to check issuer (`iss`), provide a value here
							 | 
						||
| 
								 | 
							
								* `ignoreExpiration`: if `true` do not validate the expiration of the token.
							 | 
						||
| 
								 | 
							
								* `maxAge`: optional sets an expiration based on the `iat` field. Eg `2h`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// verify a token symmetric - synchronous
							 | 
						||
| 
								 | 
							
								var decoded = jwt.verify(token, 'shhhhh');
							 | 
						||
| 
								 | 
							
								console.log(decoded.foo) // bar
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// verify a token symmetric
							 | 
						||
| 
								 | 
							
								jwt.verify(token, 'shhhhh', function(err, decoded) {
							 | 
						||
| 
								 | 
							
								  console.log(decoded.foo) // bar
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// invalid token - synchronous
							 | 
						||
| 
								 | 
							
								try {
							 | 
						||
| 
								 | 
							
								  var decoded = jwt.verify(token, 'wrong-secret');
							 | 
						||
| 
								 | 
							
								} catch(err) {
							 | 
						||
| 
								 | 
							
								  // err
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// invalid token
							 | 
						||
| 
								 | 
							
								jwt.verify(token, 'wrong-secret', function(err, decoded) {
							 | 
						||
| 
								 | 
							
								  // err
							 | 
						||
| 
								 | 
							
								  // decoded undefined
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// verify a token asymmetric
							 | 
						||
| 
								 | 
							
								var cert = fs.readFileSync('public.pem');  // get public key
							 | 
						||
| 
								 | 
							
								jwt.verify(token, cert, function(err, decoded) {
							 | 
						||
| 
								 | 
							
								  console.log(decoded.foo) // bar
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// verify audience
							 | 
						||
| 
								 | 
							
								var cert = fs.readFileSync('public.pem');  // get public key
							 | 
						||
| 
								 | 
							
								jwt.verify(token, cert, { audience: 'urn:foo' }, function(err, decoded) {
							 | 
						||
| 
								 | 
							
								  // if audience mismatch, err == invalid audience
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// verify issuer
							 | 
						||
| 
								 | 
							
								var cert = fs.readFileSync('public.pem');  // get public key
							 | 
						||
| 
								 | 
							
								jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer' }, function(err, decoded) {
							 | 
						||
| 
								 | 
							
								  // if issuer mismatch, err == invalid issuer
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// alg mismatch
							 | 
						||
| 
								 | 
							
								var cert = fs.readFileSync('public.pem'); // get public key
							 | 
						||
| 
								 | 
							
								jwt.verify(token, cert, { algorithms: ['RS256'] }, function (err, payload) {
							 | 
						||
| 
								 | 
							
								  // if token alg != RS256,  err == invalid signature
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### jwt.decode(token [, options])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(Synchronous) Returns the decoded payload without verifying if the signature is valid.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								__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.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`token` is the JsonWebToken string
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`options`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								* `json`: force JSON.parse on the payload even if the header doesn't contain `"typ":"JWT"`.
							 | 
						||
| 
								 | 
							
								* `complete`: return an object with the decoded payload and header.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Example
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// get the decoded payload ignoring signature, no secretOrPrivateKey needed
							 | 
						||
| 
								 | 
							
								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)
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Errors & Codes
							 | 
						||
| 
								 | 
							
								Possible thrown errors during verification.
							 | 
						||
| 
								 | 
							
								Error is the first argument of the verification callback.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### TokenExpiredError
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Thrown error if the token is expired.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Error object:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								* name: 'TokenExpiredError'
							 | 
						||
| 
								 | 
							
								* message: 'jwt expired'
							 | 
						||
| 
								 | 
							
								* expiredAt: [ExpDate]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								jwt.verify(token, 'shhhhh', function(err, decoded) {
							 | 
						||
| 
								 | 
							
								  if (err) {
							 | 
						||
| 
								 | 
							
								    /*
							 | 
						||
| 
								 | 
							
								      err = {
							 | 
						||
| 
								 | 
							
								        name: 'TokenExpiredError',
							 | 
						||
| 
								 | 
							
								        message: 'jwt expired',
							 | 
						||
| 
								 | 
							
								        expiredAt: 1408621000
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    */
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### JsonWebTokenError
							 | 
						||
| 
								 | 
							
								Error object:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								* name: 'JsonWebTokenError'
							 | 
						||
| 
								 | 
							
								* message:
							 | 
						||
| 
								 | 
							
								  * 'jwt malformed'
							 | 
						||
| 
								 | 
							
								  * 'jwt signature is required'
							 | 
						||
| 
								 | 
							
								  * 'invalid signature'
							 | 
						||
| 
								 | 
							
								  * 'jwt audience invalid. expected: [OPTIONS AUDIENCE]'
							 | 
						||
| 
								 | 
							
								  * 'jwt issuer invalid. expected: [OPTIONS ISSUER]'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								jwt.verify(token, 'shhhhh', function(err, decoded) {
							 | 
						||
| 
								 | 
							
								  if (err) {
							 | 
						||
| 
								 | 
							
								    /*
							 | 
						||
| 
								 | 
							
								      err = {
							 | 
						||
| 
								 | 
							
								        name: 'JsonWebTokenError',
							 | 
						||
| 
								 | 
							
								        message: 'jwt malformed'
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    */
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Algorithms supported
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Array of supported algorithms. The following algorithms are currently supported.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								alg Parameter Value | Digital Signature or MAC Algorithm
							 | 
						||
| 
								 | 
							
								----------------|----------------------------
							 | 
						||
| 
								 | 
							
								HS256 | HMAC using SHA-256 hash algorithm
							 | 
						||
| 
								 | 
							
								HS384 | HMAC using SHA-384 hash algorithm
							 | 
						||
| 
								 | 
							
								HS512 | HMAC using SHA-512 hash algorithm
							 | 
						||
| 
								 | 
							
								RS256 | RSASSA using SHA-256 hash algorithm
							 | 
						||
| 
								 | 
							
								RS384 | RSASSA using SHA-384 hash algorithm
							 | 
						||
| 
								 | 
							
								RS512 | RSASSA using SHA-512 hash algorithm
							 | 
						||
| 
								 | 
							
								ES256 | ECDSA using P-256 curve and SHA-256 hash algorithm
							 | 
						||
| 
								 | 
							
								ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm
							 | 
						||
| 
								 | 
							
								ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm
							 | 
						||
| 
								 | 
							
								none | No digital signature or MAC value included
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Issue Reporting
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If 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.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# TODO
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								* X.509 certificate chain is not checked
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Author
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[Auth0](https://auth0.com)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## License
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info.
							 |