未达到的功能
functions not being reached
我正在尝试建立登录服务原型,这是我正在进行的这个个人项目的服务器端部分的第一步。我试图在这里和这里引用代码,因为它来自Learning Node.js(Marc Wandschneider)的书,该书已经出版了三年,因此已经被证明是有效的。
我的实际服务器代码可以在这个StackOverflow链接中找到。我跳过了数据库部分,因为我在启动它时遇到了问题,相反,我将./helpers/users.js
设置为:
exports.version = "0.0.1";
var async = require('async'),
bcrypt = require('bcrypt');
var helpers = require('./helpers.js');
function User(id, email, displayName, password, deleted)
{
this.userID = id;
this.email = email;
this.displayName = displayName;
if (User.connectedToDatabase) this._password = password;
else
{
bcrypt.genSalt(10, function (err, salt) {
// this, for some reason, isn't getting called. Literally, I never see "I'm here"
console.log("I'm here...");
bcrypt.hash(password, salt, function (err, hash) {
if (!err)
{
this._password = hash;
console.log("this._password == " + this._password);
}
else
{
console.log("Error occurred: ");
console.log(err);
}
})
});
}
//this._password = password;
this.deleted = deleted;
}
User.connectedToDatabase = false;
User.prototype.userID = 0;
User.prototype.email = null;
User.prototype.displayName = null;
User.prototype._password = null;
User.prototype.deleted = false;
User.prototype.checkPassword = function (password, callback)
{
bcrypt.compare(password, this._password, callback); // returns false
}
User.prototype.responseObject = function() {
return {
id: this.userID,
email: this.email,
displayName: this.displayName
};
}
exports.login = function (req, res) {
var dblessPrototype = true;
// get email address from req.body, trim it and lowercase it
var email = req.body.emailAddress ?
req.body.emailAddress.trim().toLowerCase() :
"";
// begin the login process
async.waterfall([
// prelimninary verification: make sure email,password are not empty, and that email is of valid format
function(cb)
{
// if no email address
if (!email)
{
// send error via cb
cb(helpers.missingData("email_address"));
}
// if '@' not found in email address
else if (email.indexOf('@') == -1)
{
// then email address is invalid
cb(helpers.invalidData("email_address"));
}
// if password is missing from req.body
else if (!req.body.password)
{
// tell next function about that
cb(helpers.missingData("password"));
}
// we are ready to move on otherwise
else cb(null);
},
// TODO: lookup by email address
// check the password
function (userData, cb)
{
var u;
if (dblessPrototype)
{
u = new User(0,
"admin@mikewarren.me",
"SampleAdmin",
"Sample0x50617373");
}
else
{
u = new User(userData);
}
console.log("u._password == " + u._password);
console.log("req.body.password == " + req.body.password);
u.checkPassword(req.body.password, cb);
},
// time to set status of authenticiation
function (authOK, cb)
{
console.log("authOK == " + authOK);
if (!authOK)
{
cb(helpers.authFailed());
return;
}
// set status of authenticiation in req.session
req.session.loggedIn = true;
req.session.emailAddress = req.body.emailAddress;
req.session.loggedInTime = new Date();
}
],
function (err, results)
{
if (err)
{
console.log(JSON.stringify(err, null, ''t'));
if (err.code != "already_logged_in")
{
helpers.sendFailure(res, err);
console.log("Already logged in...");
}
}
else
{
helpers.sendSuccess(res, { loggedIn: true });
console.log("Log in successful...");
}
});
}
在密码检查中,u._password
为空(它从未被设置,这意味着异步bcrypt.genSalt()
代码没有被调用。此外,数组中的最后一个函数,即async.waterfall()
的第一个参数,也没有调用async.waterfall()
的最后一个子参数。
为什么不调用这些函数,我该怎么办?
编辑:我通过替换使异步密码加密同步
bcrypt.genSalt(10, function (err, salt) {
// this, for some reason, isn't getting called. Literally, I never see "I'm here"
console.log("I'm here...");
bcrypt.hash(password, salt, function (err, hash) {
if (!err)
{
this._password = hash;
console.log("this._password == " + this._password);
}
else
{
console.log("Error occurred: ");
console.log(err);
}
})
});
带this._password = bcrypt.hashSync(password, bcrypt.genSaltSync(10));
它进入密码比较部分,挂起一段时间,然后进入数组的下一个(最后一个)元素,而不向控制台打印任何内容。就好像那个元素被跳过了。
EDIT下载完整的应用程序并在家里摆弄它之后。
我更改了您的代码以包含setTimeout方法,并在User函数中强制执行了this
上下文。在我自己的机器上运行所有的代码,我从你的git repo下载了这些代码,我得到了用户身份验证,应用程序查找不存在的index.html。所以身份验证正在工作!
代码没有等待salt和hash完成后再继续。如果你正在向数据库写入,你可以进行"预"保存并使用promise。但这会给你一个暂时的解决办法。
function (cb, userData)
{
var u;
if (dblessPrototype)
{
var authOK;
u = new User(0,
"admin@mikewarren.me",
"SampleAdmin",
"Sample0x50617373");
setTimeout(function () {
console.log("u._password == " + u._password);
console.log("req.body.password == " + req.body.password);
console.log(u)
u.checkPassword(req.body.password, function(err, res) {
if (err) {
console.log(err)
} else {
console.log(res)
// USER AUTHENTICATED
cb(null, true)
}
return res;
});
}, 1000)
}
else
{
u = new User(userData);
}
}
在用户对象生成器中将this
分配给self
function User(id, email, displayName, password, deleted)
{
this.userID = id;
this.email = email;
this.displayName = displayName;
var self = this
if (User.connectedToDatabase) this._password = password;
else
{
bcrypt.genSalt(10, function (err, salt) {
// this, for some reason, isn't getting called. Literally, I never see "I'm here"
console.log("I'm here...");
bcrypt.hash(password, salt, function (err, hash) {
if (!err)
{
self._password = hash;
console.log("this._password == " + self._password);
}
else
{
console.log("Error occurred: ");
console.log(err);
}
})
});
}
// this._password = password;
this.deleted = deleted;
}
我应该补充一点,使用setTimeout不是一种推荐的方法,而是一种展示问题所在的方法。理想情况下,这应该使用回调、promise或生成器来完成。
- 确认框功能未定义
- 自动完成功能未启动
- 使用自动完成功能未正确选择项目
- 文档高度未达到全高
- JQuery Mobile追加新按钮的行为未达到预期
- 创建可在任何地方使用的 JS 函数?范围和功能“未定义”的问题
- 与 HTML 中的按钮关联的功能 - 未按预期工作
- 基本 webpack 不适用于按钮单击功能 - 未捕获的引用错误:未定义
- 角度控制器功能未运行
- 自动播放功能未在 JS 中执行
- 快速路线功能未吊装
- Array.splice()的行为未达到预期
- AngularJS控制器功能未执行
- 功能未在按键上运行点击电话间隙
- Ajax未达到'成功'用于登录表单
- SetTimeout功能未发生
- HTML5 localMediaStream停止功能未释放网络摄像头/硬件
- Socket.io授权功能未更新会话数据
- 滑块未达到工作高度
- 未达到的功能