-
Notifications
You must be signed in to change notification settings - Fork 215
/
Copy pathstrategy.js
139 lines (115 loc) · 4.97 KB
/
strategy.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
var passport = require('passport-strategy')
, auth_hdr = require('./auth_header')
, util = require('util')
, url = require('url')
, assign = require('./helpers/assign.js');
/**
* Strategy constructor
*
* @param options
* secretOrKey: String or buffer containing the secret or PEM-encoded public key. Required unless secretOrKeyProvider is provided.
* secretOrKeyProvider: callback in the format secretOrKeyProvider(request, rawJwtToken, done)`,
* which should call done with a secret or PEM-encoded public key
* (asymmetric) for the given undecoded jwt token string and request
* combination. done has the signature function done(err, secret).
* REQUIRED unless `secretOrKey` is provided.
* jwtFromRequest: (REQUIRED) Function that accepts a request as the only parameter and returns the either JWT as a string or null
* issuer: If defined issuer will be verified against this value
* audience: If defined audience will be verified against this value
* algorithms: List of strings with the names of the allowed algorithms. For instance, ["HS256", "HS384"].
* ignoreExpiration: if true do not validate the expiration of the token.
* passReqToCallback: If true the verify callback will be called with args (request, jwt_payload, done_callback).
* @param verify - Verify callback with args (jwt_payload, done_callback) if passReqToCallback is false,
* (request, jwt_payload, done_callback) if true.
*/
function JwtStrategy(options, verify) {
passport.Strategy.call(this);
this.name = 'jwt';
this._secretOrKeyProvider = options.secretOrKeyProvider;
if (options.secretOrKey) {
if (this._secretOrKeyProvider) {
throw new TypeError('JwtStrategy has been given both a secretOrKey and a secretOrKeyProvider');
}
this._secretOrKeyProvider = function (request, rawJwtToken, done) {
done(null, options.secretOrKey)
};
}
if (!this._secretOrKeyProvider) {
throw new TypeError('JwtStrategy requires a secret or key');
}
this._verify = verify;
if (!this._verify) {
throw new TypeError('JwtStrategy requires a verify callback');
}
this._jwtFromRequest = options.jwtFromRequest;
if (!this._jwtFromRequest) {
throw new TypeError('JwtStrategy requires a function to retrieve jwt from requests (see option jwtFromRequest)');
}
this._passReqToCallback = options.passReqToCallback;
var jsonWebTokenOptions = options.jsonWebTokenOptions || {};
//for backwards compatibility, still allowing you to pass
//audience / issuer / algorithms / ignoreExpiration
//on the options.
this._verifOpts = assign({}, jsonWebTokenOptions, {
audience: options.audience,
issuer: options.issuer,
algorithms: options.algorithms,
ignoreExpiration: !!options.ignoreExpiration
});
}
util.inherits(JwtStrategy, passport.Strategy);
/**
* Allow for injection of JWT Verifier.
*
* This improves testability by allowing tests to cleanly isolate failures in the JWT Verification
* process from failures in the passport related mechanics of authentication.
*
* Note that this should only be replaced in tests.
*/
JwtStrategy.JwtVerifier = require('./verify_jwt');
/**
* Authenticate request based on JWT obtained from header or post body
*/
JwtStrategy.prototype.authenticate = function(req, options) {
var self = this;
var token = self._jwtFromRequest(req);
if (!token) {
return self.fail(new Error("No auth token"));
}
this._secretOrKeyProvider(req, token, function(secretOrKeyError, secretOrKey) {
if (secretOrKeyError) {
self.fail(secretOrKeyError)
} else {
// Verify the JWT
JwtStrategy.JwtVerifier(token, secretOrKey, self._verifOpts, function(jwt_err, payload) {
if (jwt_err) {
return self.fail(jwt_err);
} else {
// Pass the parsed token to the user
var verified = function(err, user, info) {
if(err) {
return self.error(err);
} else if (!user) {
return self.fail(info);
} else {
return self.success(user, info);
}
};
try {
if (self._passReqToCallback) {
self._verify(req, payload, verified);
} else {
self._verify(payload, verified);
}
} catch(ex) {
self.error(ex);
}
}
});
}
});
};
/**
* Export the Jwt Strategy
*/
module.exports = JwtStrategy;