UNPKG

3.91 kBJavaScriptView Raw
1var passport = require('passport-strategy')
2 , auth_hdr = require('./auth_header')
3 , util = require('util');
4
5// Note: express http converts all headers
6// to lower case.
7var AUTH_HEADER = "authorization"
8 , DEFAULT_AUTH_SCHEME = "JWT"
9
10/**
11 * Strategy constructor
12 *
13 * @param options
14 * secretOrKey - (REQUIRED) String or buffer containing the secret or PEM-encoded public key
15 * issuer: If defined issuer will be verified against this value
16 * audience: If defined audience will be verified against this value
17 * tokenBodyField: Field in request body containing token. Default is auth_token.
18 * authScheme: Expected scheme when JWT can be found in HTTP Authorize header. Default is JWT.
19 * passReqToCallback: If true the, the verify callback will be called with args (request, jwt_payload, done_callback).
20 * @param verify - Verify callback with args (jwt_payload, done_callback) if passReqToCallback is false,
21 * (request, jwt_payload, done_callback) if true.
22 */
23function JwtStrategy(options, verify) {
24
25 passport.Strategy.call(this);
26 this.name = 'jwt';
27
28 this._secretOrKey = options.secretOrKey;
29 if (!this._secretOrKey) {
30 throw new TypeError('JwtStrategy requires a secret or key');
31 }
32
33 this._verify = verify;
34 if (!this._verify) {
35 throw new TypeError('JwtStrategy requires a verify callback');
36 }
37
38 this._passReqToCallback = options.passReqToCallback;
39 this._authScheme = options.authScheme || DEFAULT_AUTH_SCHEME;
40 this._tokenBodyField = options.tokenBodyField;
41 this._verifOpts = {}
42
43 if (options.issuer) {
44 this._verifOpts.issuer = options.issuer;
45 }
46
47 if (options.audience) {
48 this._verifOpts.audience = options.audience;
49 }
50
51};
52util.inherits(JwtStrategy, passport.Strategy);
53
54
55
56/**
57 * Allow for injection of JWT Verifier.
58 *
59 * This improves testability by allowing tests to cleanly isolate failures in the JWT Verification
60 * process from failures in the passport related mechanics of authentication.
61 *
62 * Note that this should only be replaced in tests.
63 */
64JwtStrategy.JwtVerifier = require('./verify_jwt');
65
66
67
68/**
69 * Authenticate request based on JWT obtained from header or post body
70 */
71JwtStrategy.prototype.authenticate = function(req, options) {
72 var self = this;
73 var token = null;
74 // Extract the jwt from the request
75 // Try the header first
76 if( req.headers[AUTH_HEADER]) {
77 var auth_params = auth_hdr.parse(req.headers[AUTH_HEADER]);
78 if (!auth_params) {
79 return self.fail(new Error("Invalid authorization header"));
80 }
81 if (self._authScheme === auth_params.scheme) {
82 token = auth_params.value;
83 }
84 }
85
86 // If not in the header try the body
87 if (!token && req.body) {
88 token = req.body.auth_token;
89 }
90
91 if (!token) {
92 return self.fail(new Error("No auth token"));
93 }
94
95 // Verify the JWT
96 JwtStrategy.JwtVerifier(token, this._secretOrKey, this._verifOpts, function(jwt_err, payload) {
97 if (jwt_err) {
98 return self.fail(jwt_err);
99 } else {
100 // Pass the parsed token to the user
101 var verified = function(err, user, info) {
102 if(err) {
103 return self.error(err);
104 } else if (!user) {
105 return self.fail(info);
106 } else {
107 return self.success(user, info);
108 }
109 };
110
111 try {
112 if (self._passReqToCallback) {
113 self._verify(req, payload, verified);
114 } else {
115 self._verify(payload, verified);
116 }
117 } catch(ex) {
118 self.error(ex);
119 }
120 }
121 });
122};
123
124
125
126/**
127 * Export the Jwt Strategy
128 */
129 module.exports = JwtStrategy;