var http = require('http'); /*! * Connect - basicAuth * Copyright(c) 2010 Sencha Inc. * Copyright(c) 2011 TJ Holowaychuk * MIT Licensed */ /** * Basic Auth: * * Status: Deprecated. No bug reports or pull requests are welcomed * for this middleware. However, this middleware will not be removed. * Instead, you should use [basic-auth](https://github.com/visionmedia/node-basic-auth). * * Enfore basic authentication by providing a `callback(user, pass)`, * which must return `true` in order to gain access. Alternatively an async * method is provided as well, invoking `callback(user, pass, callback)`. Populates * `req.user`. The final alternative is simply passing username / password * strings. * * Simple username and password * * connect(connect.basicAuth('username', 'password')); * * Callback verification * * connect() * .use(connect.basicAuth(function(user, pass){ * return 'tj' == user && 'wahoo' == pass; * })) * * Async callback verification, accepting `fn(err, user)`. * * connect() * .use(connect.basicAuth(function(user, pass, fn){ * User.authenticate({ user: user, pass: pass }, fn); * })) * * @param {Function|String} callback or username * @param {String} realm * @api public */ module.exports = function basicAuth(callback, realm) { var username, password; // user / pass strings if ('string' == typeof callback) { username = callback; password = realm; if ('string' != typeof password) throw new Error('password argument required'); realm = arguments[2]; callback = function(user, pass){ return user == username && pass == password; } } realm = realm || 'Authorization Required'; return function(req, res, next) { var authorization = req.headers.authorization; if (req.user) return next(); if (!authorization) return unauthorized(res, realm); var parts = authorization.split(' '); if (parts.length !== 2) return next(error(400)); var scheme = parts[0] , credentials = new Buffer(parts[1], 'base64').toString() , index = credentials.indexOf(':'); if ('Basic' != scheme || index < 0) return next(error(400)); var user = credentials.slice(0, index) , pass = credentials.slice(index + 1); // async if (callback.length >= 3) { callback(user, pass, function(err, user){ if (err || !user) return unauthorized(res, realm); req.user = req.remoteUser = user; next(); }); // sync } else { if (callback(user, pass)) { req.user = req.remoteUser = user; next(); } else { unauthorized(res, realm); } } } }; /** * Respond with 401 "Unauthorized". * * @param {ServerResponse} res * @param {String} realm * @api private */ function unauthorized(res, realm) { res.statusCode = 401; res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"'); res.end('Unauthorized'); }; /** * Generate an `Error` from the given status `code` * and optional `msg`. * * @param {Number} code * @param {String} msg * @return {Error} * @api private */ function error(code, msg){ var err = new Error(msg || http.STATUS_CODES[code]); err.status = code; return err; };