1 | # jwks-rsa
|
2 |
|
3 | [![CircleCI][circle-image]][circle-url]
|
4 | [![codecov][codecov-image]][codecov-url]
|
5 | [![NPM version][npm-image]][npm-url]
|
6 | [![License][license-image]][license-url]
|
7 | [![Downloads][downloads-image]][downloads-url]
|
8 |
|
9 | A library to retrieve RSA signing keys from a JWKS (JSON Web Key Set) endpoint.
|
10 |
|
11 | > npm install --save jwks-rsa
|
12 |
|
13 | ## Usage
|
14 |
|
15 | You'll provide the client with the JWKS endpoint which exposes your signing keys. Using the `getSigningKey` you can then get the signing key that matches a specific `kid`.
|
16 |
|
17 | ```js
|
18 | const jwksClient = require('jwks-rsa');
|
19 |
|
20 | const client = jwksClient({
|
21 | strictSsl: true, // Default value
|
22 | jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json',
|
23 | requestHeaders: {}, // Optional
|
24 | requestAgentOptions: {}, // Optional
|
25 | proxy: '[protocol]://[username]:[pass]@[address]:[port]', // Optional
|
26 | });
|
27 |
|
28 | const kid = 'RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg';
|
29 | client.getSigningKey(kid, (err, key) => {
|
30 | const signingKey = key.getPublicKey();
|
31 |
|
32 | // Now I can use this to configure my Express or Hapi middleware
|
33 | });
|
34 | ```
|
35 |
|
36 | Integrations are also provided with:
|
37 |
|
38 | - [express/express-jwt](examples/express-demo)
|
39 | - [express/passport-jwt](examples/passport-demo)
|
40 | - [hapi/hapi-auth-jwt2](examples/hapi-demo)
|
41 | - [koa/koa-jwt](examples/koa-demo)
|
42 |
|
43 | ### Caching
|
44 |
|
45 | By default, signing key verification results are cached in order to prevent excessive HTTP requests to the JWKS endpoint. If a signing key matching the `kid` is found, this will be cached and the next time this `kid` is requested the signing key will be served from the cache. The caching behavior can be configured as seen below:
|
46 |
|
47 | ```js
|
48 | const jwksClient = require('jwks-rsa');
|
49 |
|
50 | const client = jwksClient({
|
51 | cache: true, // Default Value
|
52 | cacheMaxEntries: 5, // Default value
|
53 | cacheMaxAge: ms('10m'), // Default value
|
54 | jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json'
|
55 | });
|
56 |
|
57 | const kid = 'RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg';
|
58 | client.getSigningKey(kid, (err, key) => {
|
59 | const signingKey = key.getPublicKey();
|
60 |
|
61 | // Now I can use this to configure my Express or Hapi middleware
|
62 | });
|
63 | ```
|
64 |
|
65 | ### Rate Limiting
|
66 |
|
67 | Even if caching is enabled the library will call the JWKS endpoint if the `kid` is not available in the cache, because a key rotation could have taken place. To prevent attackers to send many random `kid`s you can also configure rate limiting. This will allow you to limit the number of calls that are made to the JWKS endpoint per minute (because it would be highly unlikely that signing keys are rotated multiple times per minute).
|
68 |
|
69 | ```js
|
70 | const jwksClient = require('jwks-rsa');
|
71 |
|
72 | const client = jwksClient({
|
73 | rateLimit: true,
|
74 | jwksRequestsPerMinute: 10, // Default value
|
75 | jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json'
|
76 | });
|
77 |
|
78 | const kid = 'RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg';
|
79 | client.getSigningKey(kid, (err, key) => {
|
80 | const signingKey = key.getPublicKey();
|
81 |
|
82 | // Now I can use this to configure my Express or Hapi middleware
|
83 | });
|
84 | ```
|
85 |
|
86 | ### Using AgentOptions for TLS/SSL Configuration
|
87 |
|
88 | The `requestAgentOptions` property can be used to configure SSL/TLS options. An
|
89 | example use case is providing a trusted private (i.e. enterprise/corporate) root
|
90 | certificate authority to establish TLS communication with the `jwks_uri`.
|
91 |
|
92 | ```js
|
93 | const jwksClient = require("jwks-rsa");
|
94 | const client = jwksClient({
|
95 | strictSsl: true, // Default value
|
96 | jwksUri: 'https://my-enterprise-id-provider/.well-known/jwks.json',
|
97 | requestHeaders: {}, // Optional
|
98 | requestAgentOptions: {
|
99 | ca: fs.readFileSync(caFile)
|
100 | }
|
101 | });
|
102 | ```
|
103 |
|
104 | For more information, see [the NodeJS request library `agentOptions`
|
105 | documentation](https://github.com/request/request#using-optionsagentoptions).
|
106 |
|
107 | ## Running Tests
|
108 |
|
109 | ```
|
110 | npm run test
|
111 | ```
|
112 |
|
113 | ## Showing Trace Logs
|
114 |
|
115 | To show trace logs you can set the following environment variable:
|
116 |
|
117 | ```
|
118 | DEBUG=jwks
|
119 | ```
|
120 |
|
121 | Output:
|
122 |
|
123 | ```
|
124 | jwks Retrieving keys from http://my-authz-server/.well-known/jwks.json +5ms
|
125 | jwks Keys: +8ms [ { alg: 'RS256',
|
126 | kty: 'RSA',
|
127 | use: 'sig',
|
128 | x5c: [ 'pk1' ],
|
129 | kid: 'ABC' },
|
130 | { alg: 'RS256', kty: 'RSA', use: 'sig', x5c: [], kid: '123' } ]
|
131 | ```
|
132 |
|
133 | ## License
|
134 |
|
135 | This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info.
|
136 |
|
137 | [circle-image]: https://img.shields.io/circleci/build/github/auth0/node-jwks-rsa/master?style=flat-square
|
138 | [circle-url]: https://circleci.com/gh/auth0/node-jwks-rsa/tree/master
|
139 | [codecov-image]: https://img.shields.io/codecov/c/github/auth0/node-jwks-rsa?style=flat-square
|
140 | [codecov-url]: https://codecov.io/gh/auth0/node-jwks-rsa
|
141 | [npm-image]: https://img.shields.io/npm/v/jwks-rsa.svg?style=flat-square
|
142 | [npm-url]: https://npmjs.org/package/jwks-rsa
|
143 | [license-image]: http://img.shields.io/npm/l/jwks-rsa.svg?style=flat-square
|
144 | [license-url]: #license
|
145 | [downloads-image]: http://img.shields.io/npm/dm/jwks-rsa.svg?style=flat-square
|
146 | [downloads-url]: https://npmjs.org/package/jwks-rsa
|