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.
134 lines
2.3 KiB
134 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
|
|
}
|