You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
2.3 KiB
133 lines
2.3 KiB
/*! |
|
* basic-auth |
|
* Copyright(c) 2013 TJ Holowaychuk |
|
* Copyright(c) 2014 Jonathan Ong |
|
* Copyright(c) 2015-2016 Douglas Christopher Wilson |
|
* MIT Licensed |
|
*/ |
|
|
|
'use strict' |
|
|
|
/** |
|
* Module dependencies. |
|
* @private |
|
*/ |
|
|
|
var Buffer = require('safe-buffer').Buffer |
|
|
|
/** |
|
* Module exports. |
|
* @public |
|
*/ |
|
|
|
module.exports = auth |
|
module.exports.parse = parse |
|
|
|
/** |
|
* RegExp for basic auth credentials |
|
* |
|
* credentials = auth-scheme 1*SP token68 |
|
* auth-scheme = "Basic" ; case insensitive |
|
* token68 = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" ) *"=" |
|
* @private |
|
*/ |
|
|
|
var CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/ |
|
|
|
/** |
|
* RegExp for basic auth user/pass |
|
* |
|
* user-pass = userid ":" password |
|
* userid = *<TEXT excluding ":"> |
|
* password = *TEXT |
|
* @private |
|
*/ |
|
|
|
var USER_PASS_REGEXP = /^([^:]*):(.*)$/ |
|
|
|
/** |
|
* Parse the Authorization header field of a request. |
|
* |
|
* @param {object} req |
|
* @return {object} with .name and .pass |
|
* @public |
|
*/ |
|
|
|
function auth (req) { |
|
if (!req) { |
|
throw new TypeError('argument req is required') |
|
} |
|
|
|
if (typeof req !== 'object') { |
|
throw new TypeError('argument req is required to be an object') |
|
} |
|
|
|
// get header |
|
var header = getAuthorization(req) |
|
|
|
// parse header |
|
return parse(header) |
|
} |
|
|
|
/** |
|
* Decode base64 string. |
|
* @private |
|
*/ |
|
|
|
function decodeBase64 (str) { |
|
return Buffer.from(str, 'base64').toString() |
|
} |
|
|
|
/** |
|
* Get the Authorization header from request object. |
|
* @private |
|
*/ |
|
|
|
function getAuthorization (req) { |
|
if (!req.headers || typeof req.headers !== 'object') { |
|
throw new TypeError('argument req is required to have headers property') |
|
} |
|
|
|
return req.headers.authorization |
|
} |
|
|
|
/** |
|
* Parse basic auth to object. |
|
* |
|
* @param {string} string |
|
* @return {object} |
|
* @public |
|
*/ |
|
|
|
function parse (string) { |
|
if (typeof string !== 'string') { |
|
return undefined |
|
} |
|
|
|
// parse header |
|
var match = CREDENTIALS_REGEXP.exec(string) |
|
|
|
if (!match) { |
|
return undefined |
|
} |
|
|
|
// decode user pass |
|
var userPass = USER_PASS_REGEXP.exec(decodeBase64(match[1])) |
|
|
|
if (!userPass) { |
|
return undefined |
|
} |
|
|
|
// return credentials object |
|
return new Credentials(userPass[1], userPass[2]) |
|
} |
|
|
|
/** |
|
* Object to represent user credentials. |
|
* @private |
|
*/ |
|
|
|
function Credentials (name, pass) { |
|
this.name = name |
|
this.pass = pass |
|
}
|
|
|