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.

260 lines
8.6 KiB

  1. # jsonwebtoken [![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)
  2. An implementation of [JSON Web Tokens](https://tools.ietf.org/html/rfc7519).
  3. This was developed against `draft-ietf-oauth-json-web-token-08`. It makes use of [node-jws](https://github.com/brianloveswords/node-jws)
  4. # Install
  5. ```bash
  6. $ npm install jsonwebtoken
  7. ```
  8. # Usage
  9. ### jwt.sign(payload, secretOrPrivateKey, options, [callback])
  10. (Asynchronous) If a callback is supplied, callback is called with the `err` or the JWT.
  11. (Synchronous) Returns the JsonWebToken as string
  12. `payload` could be an object literal, buffer or string. *Please note that* `exp` is only set if the payload is an object literal.
  13. `secretOrPrivateKey` is a string or buffer containing either the secret for HMAC algorithms, or the PEM
  14. encoded private key for RSA and ECDSA.
  15. `options`:
  16. * `algorithm` (default: `HS256`)
  17. * `expiresIn`: expressed in seconds or a string describing a time span [rauchg/ms](https://github.com/rauchg/ms.js). Eg: `60`, `"2 days"`, `"10h"`, `"7d"`
  18. * `notBefore`: expressed in seconds or a string describing a time span [rauchg/ms](https://github.com/rauchg/ms.js). Eg: `60`, `"2 days"`, `"10h"`, `"7d"`
  19. * `audience`
  20. * `issuer`
  21. * `jwtid`
  22. * `subject`
  23. * `noTimestamp`
  24. * `header`
  25. If `payload` is not a buffer or a string, it will be coerced into a string using `JSON.stringify`.
  26. There are no default values for `expiresIn`, `notBefore`, `audience`, `subject`, `issuer`. These claims can also be provided in the payload directly with `exp`, `nbf`, `aud` and `sub` respectively, but you can't include in both places.
  27. The header can be customized via the `option.header` object.
  28. Generated 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`.
  29. Example
  30. ```js
  31. // sign with default (HMAC SHA256)
  32. var jwt = require('jsonwebtoken');
  33. var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
  34. //backdate a jwt 30 seconds
  35. var older_token = jwt.sign({ foo: 'bar', iat: Math.floor(Date.now() / 1000) - 30 }, 'shhhhh');
  36. // sign with RSA SHA256
  37. var cert = fs.readFileSync('private.key'); // get private key
  38. var token = jwt.sign({ foo: 'bar' }, cert, { algorithm: 'RS256'});
  39. // sign asynchronously
  40. jwt.sign({ foo: 'bar' }, cert, { algorithm: 'RS256' }, function(err, token) {
  41. console.log(token);
  42. });
  43. ```
  44. ### jwt.verify(token, secretOrPublicKey, [options, callback])
  45. (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.
  46. (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.
  47. `token` is the JsonWebToken string
  48. `secretOrPublicKey` is a string or buffer containing either the secret for HMAC algorithms, or the PEM
  49. encoded public key for RSA and ECDSA.
  50. `options`
  51. * `algorithms`: List of strings with the names of the allowed algorithms. For instance, `["HS256", "HS384"]`.
  52. * `audience`: if you want to check audience (`aud`), provide a value here
  53. * `issuer` (optional): string or array of strings of valid values for the `iss` field.
  54. * `ignoreExpiration`: if `true` do not validate the expiration of the token.
  55. * `ignoreNotBefore`...
  56. * `subject`: if you want to check subject (`sub`), provide a value here
  57. * `clockTolerance`: number of second to tolerate when checking the `nbf` and `exp` claims, to deal with small clock differences among different servers
  58. ```js
  59. // verify a token symmetric - synchronous
  60. var decoded = jwt.verify(token, 'shhhhh');
  61. console.log(decoded.foo) // bar
  62. // verify a token symmetric
  63. jwt.verify(token, 'shhhhh', function(err, decoded) {
  64. console.log(decoded.foo) // bar
  65. });
  66. // invalid token - synchronous
  67. try {
  68. var decoded = jwt.verify(token, 'wrong-secret');
  69. } catch(err) {
  70. // err
  71. }
  72. // invalid token
  73. jwt.verify(token, 'wrong-secret', function(err, decoded) {
  74. // err
  75. // decoded undefined
  76. });
  77. // verify a token asymmetric
  78. var cert = fs.readFileSync('public.pem'); // get public key
  79. jwt.verify(token, cert, function(err, decoded) {
  80. console.log(decoded.foo) // bar
  81. });
  82. // verify audience
  83. var cert = fs.readFileSync('public.pem'); // get public key
  84. jwt.verify(token, cert, { audience: 'urn:foo' }, function(err, decoded) {
  85. // if audience mismatch, err == invalid audience
  86. });
  87. // verify issuer
  88. var cert = fs.readFileSync('public.pem'); // get public key
  89. jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer' }, function(err, decoded) {
  90. // if issuer mismatch, err == invalid issuer
  91. });
  92. // verify jwt id
  93. var cert = fs.readFileSync('public.pem'); // get public key
  94. jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer', jwtid: 'jwtid' }, function(err, decoded) {
  95. // if jwt id mismatch, err == invalid jwt id
  96. });
  97. // verify subject
  98. var cert = fs.readFileSync('public.pem'); // get public key
  99. jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer', jwtid: 'jwtid', subject: 'subject' }, function(err, decoded) {
  100. // if subject mismatch, err == invalid subject
  101. });
  102. // alg mismatch
  103. var cert = fs.readFileSync('public.pem'); // get public key
  104. jwt.verify(token, cert, { algorithms: ['RS256'] }, function (err, payload) {
  105. // if token alg != RS256, err == invalid signature
  106. });
  107. ```
  108. ### jwt.decode(token [, options])
  109. (Synchronous) Returns the decoded payload without verifying if the signature is valid.
  110. __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.
  111. `token` is the JsonWebToken string
  112. `options`:
  113. * `json`: force JSON.parse on the payload even if the header doesn't contain `"typ":"JWT"`.
  114. * `complete`: return an object with the decoded payload and header.
  115. Example
  116. ```js
  117. // get the decoded payload ignoring signature, no secretOrPrivateKey needed
  118. var decoded = jwt.decode(token);
  119. // get the decoded payload and header
  120. var decoded = jwt.decode(token, {complete: true});
  121. console.log(decoded.header);
  122. console.log(decoded.payload)
  123. ```
  124. ## Errors & Codes
  125. Possible thrown errors during verification.
  126. Error is the first argument of the verification callback.
  127. ### TokenExpiredError
  128. Thrown error if the token is expired.
  129. Error object:
  130. * name: 'TokenExpiredError'
  131. * message: 'jwt expired'
  132. * expiredAt: [ExpDate]
  133. ```js
  134. jwt.verify(token, 'shhhhh', function(err, decoded) {
  135. if (err) {
  136. /*
  137. err = {
  138. name: 'TokenExpiredError',
  139. message: 'jwt expired',
  140. expiredAt: 1408621000
  141. }
  142. */
  143. }
  144. });
  145. ```
  146. ### JsonWebTokenError
  147. Error object:
  148. * name: 'JsonWebTokenError'
  149. * message:
  150. * 'jwt malformed'
  151. * 'jwt signature is required'
  152. * 'invalid signature'
  153. * 'jwt audience invalid. expected: [OPTIONS AUDIENCE]'
  154. * 'jwt issuer invalid. expected: [OPTIONS ISSUER]'
  155. * 'jwt id invalid. expected: [OPTIONS JWT ID]'
  156. * 'jwt subject invalid. expected: [OPTIONS SUBJECT]'
  157. ```js
  158. jwt.verify(token, 'shhhhh', function(err, decoded) {
  159. if (err) {
  160. /*
  161. err = {
  162. name: 'JsonWebTokenError',
  163. message: 'jwt malformed'
  164. }
  165. */
  166. }
  167. });
  168. ```
  169. ## Algorithms supported
  170. Array of supported algorithms. The following algorithms are currently supported.
  171. alg Parameter Value | Digital Signature or MAC Algorithm
  172. ----------------|----------------------------
  173. HS256 | HMAC using SHA-256 hash algorithm
  174. HS384 | HMAC using SHA-384 hash algorithm
  175. HS512 | HMAC using SHA-512 hash algorithm
  176. RS256 | RSASSA using SHA-256 hash algorithm
  177. RS384 | RSASSA using SHA-384 hash algorithm
  178. RS512 | RSASSA using SHA-512 hash algorithm
  179. ES256 | ECDSA using P-256 curve and SHA-256 hash algorithm
  180. ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm
  181. ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm
  182. none | No digital signature or MAC value included
  183. # TODO
  184. * X.509 certificate chain is not checked
  185. ## Issue Reporting
  186. 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.
  187. ## Author
  188. [Auth0](https://auth0.com)
  189. ## License
  190. This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info.