-
Notifications
You must be signed in to change notification settings - Fork 0
/
express-jwt-validator.js
72 lines (69 loc) · 3.41 KB
/
express-jwt-validator.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
const jwt = require('jsonwebtoken');
const bearerPrefix = 'Bearer';
const defaultHeader = 'authorization';
const defaultFailedStatus = 401;
const defaultSendExpiredMessage = true;
const defaultRequestAuthProp = 'authData';
const defaultStrictBearerValidation = false;
module.exports = (conf) => {
// check if conf and conf.secret are present (minimal requirement)
if (!conf || !conf.secret) {
throw new Error('No secret value provided!');
}
// check for optional conf values or use default values instead
const authHeader = conf.header ? conf.header : defaultHeader;
const rejectHttpStatus = conf.rejectHttpStatus ? conf.rejectHttpStatus : defaultFailedStatus;
const sendExpiredMessage = Object.prototype.hasOwnProperty.call(conf, 'sendExpiredMessage') ? conf.sendExpiredMessage === true : defaultSendExpiredMessage;
const requestAuthProp = conf.requestAuthProp ? conf.requestAuthProp : defaultRequestAuthProp;
const strictBearerValidation = Object.prototype.hasOwnProperty.call(conf, 'strictBearerValidation') ? conf.strictBearerValidation === true : defaultStrictBearerValidation;
// return middleware function
return (req, res, next) => {
const authorizationHeader = req.headers[authHeader];
if (typeof authorizationHeader !== 'undefined') {
const bearer = authorizationHeader.split(' ');
if (bearer.length < 2) {
if (conf.logger) conf.logger.warn('Bearer token was not sent. Denying request.');
res.sendStatus(rejectHttpStatus);
return;
}
if (strictBearerValidation) {
if (bearer.length !== 2 || bearer[0] !== bearerPrefix) {
if (conf.logger) conf.logger.warn('Strict Bearer validation failed. Denying request.');
res.sendStatus(rejectHttpStatus);
return;
}
}
const bearerToken = bearer[1];
jwt.verify(bearerToken, conf.secret, (err, authData) => {
if (err) {
if (err.name == 'TokenExpiredError') {
if (conf.logger) conf.logger.warn('Expired bearer token was sent. Denying request.');
if (sendExpiredMessage) {
// Deny TokenExpiredError with additional message payload for the ability of client re-login
res.status(rejectHttpStatus).json({ error: err.name });
return;
}
else {
// Deny expired token without additional message
res.sendStatus(rejectHttpStatus);
return;
}
}
else {
if (conf.logger) conf.logger.error('Invalid bearer token was sent. Denying request.');
res.sendStatus(rejectHttpStatus);
return;
}
} else {
req[requestAuthProp] = authData;
if (conf.logger) conf.logger.info('Token verification successful');
next();
}
});
} else {
if (conf.logger) conf.logger.warn('Authorization header was not sent. Denying request.');
res.sendStatus(rejectHttpStatus);
return;
}
}
};