2

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

服务器.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;
}

用户管理器.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) 完成之前返回了结果,但我不知道该怎么做。

谢谢您的帮助。

4

1 回答 1

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);
    }
}));
于 2013-05-29T13:49:21.007 回答