UNPKG

7.48 kBMarkdownView Raw
1# express-jwt
2
3[![Build](https://travis-ci.org/auth0/express-jwt.png)](http://travis-ci.org/auth0/express-jwt)
4
5This module provides Express middleware for validating JWTs ([JSON Web Tokens](https://jwt.io)) through the [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken/) module. The decoded JWT payload is available on the request object.
6
7## Install
8
9```
10$ npm install express-jwt
11```
12
13## Usage
14
15Basic usage using an HS256 secret:
16
17```javascript
18var jwt = require('express-jwt');
19
20app.get('/protected',
21 jwt({ secret: 'shhhhhhared-secret' }),
22 function(req, res) {
23 if (!req.user.admin) return res.sendStatus(401);
24 res.sendStatus(200);
25 });
26```
27
28The decoded JWT payload is available on the request via the `user` property. This can be configured using the `requestProperty` option ([see below](#retrieving-the-decoded-payload)).
29
30> The default behavior of the module is to extract the JWT from the `Authorization` header as an [OAuth2 Bearer token](https://oauth.net/2/bearer-tokens/).
31
32### Additional Options
33
34You can specify audience and/or issuer as well:
35
36```javascript
37jwt({
38 secret: 'shhhhhhared-secret',
39 audience: 'http://myapi/protected',
40 issuer: 'http://issuer'
41})
42```
43
44> If the JWT has an expiration (`exp`), it will be checked.
45
46If you are using a base64 URL-encoded secret, pass a `Buffer` with `base64` encoding as the secret instead of a string:
47
48```javascript
49jwt({ secret: new Buffer('shhhhhhared-secret', 'base64') })
50```
51
52Optionally you can make some paths unprotected as follows:
53
54```javascript
55app.use(jwt({ secret: 'shhhhhhared-secret'}).unless({path: ['/token']}));
56```
57
58This is especially useful when applying to multiple routes. In the example above, `path` can be a string, a regexp, or an array of any of those.
59
60> For more details on the `.unless` syntax including additional options, please see [express-unless](https://github.com/jfromaniello/express-unless).
61
62This module also support tokens signed with public/private key pairs. Instead of a secret, you can specify a Buffer with the public key
63
64```javascript
65var publicKey = fs.readFileSync('/path/to/public.pub');
66jwt({ secret: publicKey });
67```
68
69### Retrieving the Decoded Payload
70
71By default, the decoded token is attached to `req.user` but can be configured with the `requestProperty` option.
72
73
74```javascript
75jwt({ secret: publicKey, requestProperty: 'auth' });
76```
77
78The token can also be attached to the `result` object with the `resultProperty` option. This option will override any `requestProperty`.
79
80```javascript
81jwt({ secret: publicKey, resultProperty: 'locals.user' });
82```
83
84Both `resultProperty` and `requestProperty` utilize [lodash.set](https://lodash.com/docs/4.17.2#set) and will accept nested property paths.
85
86### Customizing Token Location
87
88A custom function for extracting the token from a request can be specified with
89the `getToken` option. This is useful if you need to pass the token through a
90query parameter or a cookie. You can throw an error in this function and it will
91be handled by `express-jwt`.
92
93```javascript
94app.use(jwt({
95 secret: 'hello world !',
96 credentialsRequired: false,
97 getToken: function fromHeaderOrQuerystring (req) {
98 if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
99 return req.headers.authorization.split(' ')[1];
100 } else if (req.query && req.query.token) {
101 return req.query.token;
102 }
103 return null;
104 }
105}));
106```
107
108### Multi-tenancy
109
110If you are developing an application in which the secret used to sign tokens is not static, you can provide a callback function as the `secret` parameter. The function has the signature: `function(req, payload, done)`:
111* `req` (`Object`) - The express `request` object.
112* `payload` (`Object`) - An object with the JWT claims.
113* `done` (`Function`) - A function with signature `function(err, secret)` to be invoked when the secret is retrieved.
114 * `err` (`Any`) - The error that occurred.
115 * `secret` (`String`) - The secret to use to verify the JWT.
116
117For example, if the secret varies based on the [JWT issuer](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#issDef):
118
119```javascript
120var jwt = require('express-jwt');
121var data = require('./data');
122var utilities = require('./utilities');
123
124var secretCallback = function(req, payload, done){
125 var issuer = payload.iss;
126
127 data.getTenantByIdentifier(issuer, function(err, tenant){
128 if (err) { return done(err); }
129 if (!tenant) { return done(new Error('missing_secret')); }
130
131 var secret = utilities.decrypt(tenant.secret);
132 done(null, secret);
133 });
134};
135
136app.get('/protected',
137 jwt({ secret: secretCallback }),
138 function(req, res) {
139 if (!req.user.admin) return res.sendStatus(401);
140 res.sendStatus(200);
141 });
142```
143
144### Revoked tokens
145It is possible that some tokens will need to be revoked so they cannot be used any longer. You can provide a function as the `isRevoked` option. The signature of the function is `function(req, payload, done)`:
146* `req` (`Object`) - The express `request` object.
147* `payload` (`Object`) - An object with the JWT claims.
148* `done` (`Function`) - A function with signature `function(err, revoked)` to be invoked once the check to see if the token is revoked or not is complete.
149 * `err` (`Any`) - The error that occurred.
150 * `revoked` (`Boolean`) - `true` if the JWT is revoked, `false` otherwise.
151
152For example, if the `(iss, jti)` claim pair is used to identify a JWT:
153```javascript
154var jwt = require('express-jwt');
155var data = require('./data');
156var utilities = require('./utilities');
157
158var isRevokedCallback = function(req, payload, done){
159 var issuer = payload.iss;
160 var tokenId = payload.jti;
161
162 data.getRevokedToken(issuer, tokenId, function(err, token){
163 if (err) { return done(err); }
164 return done(null, !!token);
165 });
166};
167
168app.get('/protected',
169 jwt({
170 secret: 'shhhhhhared-secret',
171 isRevoked: isRevokedCallback
172 }),
173 function(req, res) {
174 if (!req.user.admin) return res.sendStatus(401);
175 res.sendStatus(200);
176 }
177);
178```
179
180### Error handling
181
182The default behavior is to throw an error when the token is invalid, so you can add your custom logic to manage unauthorized access as follows:
183
184```javascript
185app.use(function (err, req, res, next) {
186 if (err.name === 'UnauthorizedError') {
187 res.status(401).send('invalid token...');
188 }
189});
190```
191
192You might want to use this module to identify registered users while still providing access to unregistered users. You can do this by using the option `credentialsRequired`:
193
194```javascript
195app.use(jwt({
196 secret: 'hello world !',
197 credentialsRequired: false
198}));
199```
200
201## Related Modules
202
203- [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken) — JSON Web Token sign and verification
204- [express-jwt-permissions](https://github.com/MichielDeMey/express-jwt-permissions) - Permissions middleware for JWT tokens
205
206## Tests
207
208```
209$ npm install
210$ npm test
211```
212
213## Contributors
214Check them out [here](https://github.com/auth0/express-jwt/graphs/contributors)
215
216## Issue Reporting
217
218If 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.
219
220## Author
221
222[Auth0](auth0.com)
223
224## License
225
226This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info.