stick
Version:
JSGI based webapp framework
69 lines (64 loc) • 2 kB
JavaScript
/**
* @fileOverview Basic Authentication middleware.
*
* To apply authentication to parts of your
* website configure this middleware and call the app's basicauth method with
* the URI path, user name, and SHA1 digest of the user's password as arguments for
* each path you want to protect:
*
* @example
* app.configure("basicauth");
* app.basicauth('/protected/path', 'admin',
* '30B93F320076DE1304C34673F9F524F7EA7DB709');
*
*/
var strings = require('common-utils/strings');
var base64 = require('common-utils/base64');
/**
*
* @param {Function} next the wrapped middleware chain
* @param {Object} app the Stick Application object
* @returns {Function} a JSGI middleware function
*/
exports.middleware = function basicauth(next, app) {
var config = {};
app.basicauth = function(path, role, sha1) {
config[path] = {};
// strings.digest() uses upper-case hex encoding
config[path][role] = String(sha1).toUpperCase();
};
return function basicauth(req) {
// normalize multiple slashes in request path
var path = (req.scriptName + req.pathInfo).replace(/\/+/g, '/');
var toAuth;
for (var realm in config) {
if (path.indexOf(realm) === 0) {
toAuth = config[realm];
break;
}
}
if (toAuth) {
var auth = req.headers.authorization[0];
if (auth) { // Extract credentials from HTTP.
var credentials = base64.decode(auth.replace(/Basic /, '')).split(':');
if (strings.digest(credentials[1], 'sha1') === toAuth[credentials[0]]) {
return next(req); // Authorization.
}
}
var msg = '401 Unauthorized';
return {
status:401,
headers:{
'Content-Type':'text/html',
'WWW-Authenticate':'Basic realm="Secure Area"'
},
body:[
'<html><head><title>', msg, '</title></head>',
'<body><h1>', msg, '</h1>',
'</body></html>'
]
};
}
return next(req);
};
};