This repository has been archived by the owner on Nov 28, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
token-scheme.js
executable file
·68 lines (55 loc) · 2.04 KB
/
token-scheme.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
const Boom = require('@hapi/boom')
const Hoek = require('@hapi/hoek')
const Joi = require('@hapi/joi')
const tokenScheme = function (server, { authOptions, authProvider }) {
Hoek.assert(authOptions, 'Missing authOptions')
Hoek.assert(authProvider, 'Missing authProvider')
const options = Hoek.applyToDefaults(defaults, authOptions)
Joi.assert(options, optionsSchema)
// https://github.com/hapijs/hapi/blob/master/API.md#authentication-scheme
return {
async authenticate (request, h) {
// Use headers by default
let authorization = request.raw.req.headers.authorization
// Fallback 1 : Check for cookies
if (options.allowCookieToken &&
!authorization &&
request.state[options.accessTokenName]) {
authorization = options.tokenType + ' ' + request.state[options.accessTokenName]
}
// Fallback 2 : URL Query
if (options.allowQueryToken && !authorization && request.query[options.accessTokenName]) {
authorization = options.tokenType + ' ' + request.query[options.accessTokenName]
delete request.query[options.accessTokenName]
}
// Fallback 3 : Throw Error
if (!authorization) {
throw Boom.unauthorized(null, options.tokenType)
}
// Try to parse headers
const parts = authorization.split(/\s+/)
// Ensure correct token type
if (parts[0].toLowerCase() !== options.tokenType.toLowerCase()) {
throw Boom.unauthorized(null, options.tokenType)
}
// Try to login
const token = parts[1]
const { credentials, artifacts } = await authProvider.authToken(token)
// OK
return h.authenticated({ credentials, artifacts })
}
}
}
module.exports = tokenScheme
const defaults = {
accessTokenName: 'token',
allowQueryToken: true,
allowCookieToken: true,
tokenType: 'Bearer'
}
const optionsSchema = Joi.object().keys({
accessTokenName: Joi.string().required(),
allowQueryToken: Joi.boolean(),
allowCookieToken: Joi.boolean(),
tokenType: Joi.string().required()
}).unknown(true)