Express和Mongoose的BasicAuth

时间:2013-05-29 09:29:32

标签: node.js mongodb express mongoose basic-authentication

我正在尝试向Express路径添加基本身份验证。要检查组合用户/传递是否正确,我在MongoDB数据库中读取了集合usermodels。 这是我的代码:

server.js

var normal = express.basicAuth(normalAuth);

app.get('path', normal, function(req, res){etc.});

function normalAuth(user, pass) {
  var mongo = require('./database/userManager');
  var result = false;
  mongo.start(mongo.list(function(err, data) {
      if(err) { throw err; }
      else {
        console.log('Getting list from db...');
        for(var i in data) {
          console.log('Getting details from db...');
          if(user == data[i].name && pass == data[i].pass) {
            console.log('New connection : ' + user);
            result = true;
            break;
          }
          else {
            console.log('Failed connection : ' + user);
            result = false;
          }
        }
        console.log('OK');
      }
      mongo.mongoose.connection.close();
  }));
  return result;
}

userManager.js

var mongoose = require('mongoose');

var userModel = mongoose.connection.model('usermodel', new mongoose.Schema({
    name: String,
    pass: String,
    status: { type: Boolean, default: false }
}), 'usermodels');

function start(callback) {
  mongoose.connect('mongodb://localhost/derp', function(err) {
      if(err) { throw err; }
      else { 
        console.log('Connected to database ');
      }
  });
}

function list(callback) {
  userModel.find(callback); 
}

身份验证几乎可以正常工作,它连接到数据库并获取信息。它在控制台上打印

"New connection : /*user connected*/". 

但是有一个问题:我的函数normalAuth总是返回false,所以即使我有正确的用户/传递,我也无法访问页面,我有连接窗口,好像我给错了用户/传递。我想这是因为这个函数在我的mongo.start(blabla)完成之前返回结果,但我不知道该怎么做。

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

你总是得到错误的结果,因为在 Node.js中,每个IO操作都是异步的

让我解释一下:当你调用mongo.start(...)函数时,Node.js会把它放在另一个操作队列中,因为它是IO操作。不得阻止主操作队列,这就是IO操作始终是异步的原因。 Ater mongo函数放在另一个操作队列中,您的主操作队列将继续并到达代码行:return false。无论函数mongo.start(...)将使用它做什么,它都将返回false。

解决方案是通过发送回调函数:

function normalAuth(user, pass, callbackResult) {
  var mongo = require('./database/userManager');      
  mongo.start(mongo.list(function(err, data) {
      if(err) { throw err; }
      else {
        console.log('Getting list from db...');
        for(var i in data) {
          console.log('Getting details from db...');
          if(user == data[i].name && pass == data[i].pass) {
            console.log('New connection : ' + user);
            // here you send true to callback function
            callbackResult(true);
            break;
          }
          else {
            console.log('Failed connection : ' + user);
            // here you send false to callback function
            callbackResult(false);
          }
        }
        console.log('OK');
      }
      mongo.mongoose.connection.close();
  }));
}

你可以这样称呼这个函数:

normalAuth(user, pass, function(result) {
    if(result)
        console.log("Auth OK");
    else
        console.log("Auth Failed");
}

编辑:在express.basicAuth函数中,它将被调用如下:

app.use(express.basicAuth(function(user, pass, callback) {
    normalAuth(user, pass, function(result) {     
        callback(null /* error */, result);
    }
}));