4 * Copyright(c) 2010 Sencha Inc.
5 * Copyright(c) 2011 TJ Holowaychuk
10 * Module dependencies.
13 var utils = require('../utils')
14 , unauthorized = utils.unauthorized
15 , badRequest = utils.badRequest;
18 * Enfore basic authentication by providing a `callback(user, pass)`,
19 * which must return `true` in order to gain access. Alternatively an async
20 * method is provided as well, invoking `callback(user, pass, callback)`. Populates
21 * `req.remoteUser`. The final alternative is simply passing username / password
26 * connect(connect.basicAuth('username', 'password'));
29 * connect.basicAuth(function(user, pass){
30 * return 'tj' == user & 'wahoo' == pass;
35 * connect.basicAuth(function(user, pass, fn){
36 * User.authenticate({ user: user, pass: pass }, fn);
40 * @param {Function|String} callback or username
41 * @param {String} realm
45 module.exports = function basicAuth(callback, realm) {
46 var username, password;
48 // user / pass strings
49 if ('string' == typeof callback) {
52 if ('string' != typeof password) throw new Error('password argument required');
54 callback = function(user, pass){
55 return user == username && pass == password;
59 realm = realm || 'Authorization Required';
61 return function(req, res, next) {
62 var authorization = req.headers.authorization;
64 if (req.remoteUser) return next();
65 if (!authorization) return unauthorized(res, realm);
67 var parts = authorization.split(' ')
69 , credentials = new Buffer(parts[1], 'base64').toString().split(':');
71 if ('Basic' != scheme) return badRequest(res);
74 if (callback.length >= 3) {
75 var pause = utils.pause(req);
76 callback(credentials[0], credentials[1], function(err, user){
77 if (err || !user) return unauthorized(res, realm);
78 req.remoteUser = user;
84 if (callback(credentials[0], credentials[1])) {
85 req.remoteUser = credentials[0];
88 unauthorized(res, realm);