Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ var publicKey = fs.readFileSync('/path/to/public.pub');
jwt({ secret: publicKey });
```

By default, the decoded token is attached to `req.user` but can be configured with the `requestProperty` option.
When the token can be decoded _and_ verified, by default, the decoded token is attached to `req.user` but can be configured with the `requestProperty` option.

When the token can be decoded _but not necessarily verified_, by default, the decoded token is attached to `req.decoded` regardless of if an error is thrown. The specific property set can be configured with the `decodedProperty` option. (This can be useful for error handling; see "Error handling" for more info.)

```javascript
jwt({ secret: publicKey, requestProperty: 'auth' });
Expand Down Expand Up @@ -174,6 +175,12 @@ The default behavior is to throw an error when the token is invalid, so you can
```javascript
app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') {
console.log(`error with token: ${err.message}`)
if (req.decoded) {
console.log(`The following token was decoded, but could not verified: ${req.decoded}`)
} else {
console.log(`The token could not be decoded`)
}
res.status(401).send('invalid token...');
}
});
Expand Down
2 changes: 2 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module.exports = function(options) {
var isRevokedCallback = options.isRevoked || DEFAULT_REVOKED_FUNCTION;

var _requestProperty = options.userProperty || options.requestProperty || 'user';
var _requestDecodedProperty = options.decodedProperty || options.requestDecodedProperty || 'decoded';
var _resultProperty = options.resultProperty;
var credentialsRequired = typeof options.credentialsRequired === 'undefined' ? true : options.credentialsRequired;

Expand Down Expand Up @@ -83,6 +84,7 @@ module.exports = function(options) {

try {
dtoken = jwt.decode(token, { complete: true }) || {};
set(req, _requestDecodedProperty, dtoken.payload);
} catch (err) {
return next(new UnauthorizedError('invalid_token', err));
}
Expand Down
16 changes: 16 additions & 0 deletions test/jwt.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,22 @@ describe('failure tests', function () {
});
});

it('should include decoded and not user token if jwt decodes but doesn\'t verify', function() {
var secret = 'shhhhhh';
var token = jwt.sign({foo: 'bar'}, secret);

req.headers = {};
req.headers.authorization = 'Bearer ' + token;
expressjwt({secret: 'different-shhhh'})(req, res, function(err) {
assert.ok(err);
assert.ok(req.decoded)
assert.equal(req.user, undefined)
assert.equal(err.code, 'invalid_token');
assert.equal(req.decoded.foo, 'bar');
assert.equal(err.message, 'invalid signature');
});
});

it('should throw if audience is not expected', function() {
var secret = 'shhhhhh';
var token = jwt.sign({foo: 'bar', aud: 'expected-audience'}, secret);
Expand Down