验证 Hapi.js 和 Bookshelf.js 问题
Validation with Hapi.js and Bookshelf.js issues
我正在按照他们在 bookshelf.js (http://bookshelfjs.org/#Model) 网站上提供的 login
示例进行操作,但出于某种原因,无论我是否提交密码是否错误
这是我的路线:
{
method: 'POST',
path: '/auth/login',
config: {
auth: false,
payload: { allow: 'application/json' },
handler: function(request, reply) {
var email = request.payload.email;
var pwd = request.payload.password;
User.login(email, pwd).then(function(user) {
reply(user.pick('api_token'));
}).catch(User.NotFoundError, function() {
reply({error: email + ' not found'}).code(400)
}).catch(function(err) {
console.error(err);
});
},
validate: {
payload: Joi.object().keys({
email: Joi.string().email().required(),
password: Joi.string().required()
})
}
}
}
这是我的模型:
'use strict';
var Bluebird = require('bluebird');
var bcrypt = Bluebird.promisifyAll(require('bcrypt'));
module.exports = function(bookshelf) {
var User = bookshelf.Model.extend({
tableName: 'user',
}, {
login: Bluebird.method(function(email, password) {
return new this({email: email.toLowerCase().trim()})
.fetch({require: true})
.tap(function(user) {
return bcrypt.compareAsync(password, user.get('encrypted_password'));
});
})
});
return User;
};
我不确定发生了什么。我 console.log
通过比较一个好的请求和一个坏的请求的密码得到了响应,那段代码正在运行,但就像我说的,即使我提交了一个错误的密码,用户也会被返回
是的,这里的文档是错误的。
您没有对 compareAsync
的结果执行任何操作。它 returns 一个解析为布尔值的承诺(文档 here)。
所以你可能想做这样的事情:
在某处创建错误class。我正在使用 Bookshelf 使用的 'create-error' 模块。
InvalidPasswordError = require('create-error')('InvalidPasswordError');
现在当密码不匹配时触发此错误。
login: Bluebird.method(function(email, password) {
return new this({email: email.toLowerCase().trim()})
.fetch({require: true})
.tap(function(user) {
return bcrypt.compareAsync(password, user.get('encrypted_password'))
.then(function (matches) {
if (!matches) throw new InvalidPasswordError();
}
});
})
现在按类型捕获该错误并以适当的错误响应。
handler: function(request, reply) {
var email = request.payload.email;
var pwd = request.payload.password;
User.login(email, pwd).then(function(user) {
reply(user.pick('api_token'));
}).catch(User.NotFoundError, function() {
reply({error: email + ' not found'}).code(400);
}).catch(InvalidPasswordError, function() {
reply({error: 'invalid password'}).code(400);
}).catch(function(err) {
console.error(err);
});
},
我认为 Rhys van der Waerden 提供了一个很好的解决方案。但是,要弄清楚您的代码有什么问题,请考虑以下内容(来自 bluebird 规范):
getUser().tap(function(user) {
//Like in finally, if you return a promise from the handler
//the promise is awaited for before passing the original value through
return recordStatsAsync();
}).then(function(user) {
//user is the user from getUser(), not recordStatsAsync()
});
如您所见,.then
案例得到了完整的结果,.tap
的异步部分没有提供.then
的数据。
长话短说:从 .tap
更改为 .then
,你应该会很好。但是,您将获得的结果将是 true
或 false
而不是用户数据。
我正在按照他们在 bookshelf.js (http://bookshelfjs.org/#Model) 网站上提供的 login
示例进行操作,但出于某种原因,无论我是否提交密码是否错误
这是我的路线:
{
method: 'POST',
path: '/auth/login',
config: {
auth: false,
payload: { allow: 'application/json' },
handler: function(request, reply) {
var email = request.payload.email;
var pwd = request.payload.password;
User.login(email, pwd).then(function(user) {
reply(user.pick('api_token'));
}).catch(User.NotFoundError, function() {
reply({error: email + ' not found'}).code(400)
}).catch(function(err) {
console.error(err);
});
},
validate: {
payload: Joi.object().keys({
email: Joi.string().email().required(),
password: Joi.string().required()
})
}
}
}
这是我的模型:
'use strict';
var Bluebird = require('bluebird');
var bcrypt = Bluebird.promisifyAll(require('bcrypt'));
module.exports = function(bookshelf) {
var User = bookshelf.Model.extend({
tableName: 'user',
}, {
login: Bluebird.method(function(email, password) {
return new this({email: email.toLowerCase().trim()})
.fetch({require: true})
.tap(function(user) {
return bcrypt.compareAsync(password, user.get('encrypted_password'));
});
})
});
return User;
};
我不确定发生了什么。我 console.log
通过比较一个好的请求和一个坏的请求的密码得到了响应,那段代码正在运行,但就像我说的,即使我提交了一个错误的密码,用户也会被返回
是的,这里的文档是错误的。
您没有对 compareAsync
的结果执行任何操作。它 returns 一个解析为布尔值的承诺(文档 here)。
所以你可能想做这样的事情:
在某处创建错误class。我正在使用 Bookshelf 使用的 'create-error' 模块。
InvalidPasswordError = require('create-error')('InvalidPasswordError');
现在当密码不匹配时触发此错误。
login: Bluebird.method(function(email, password) {
return new this({email: email.toLowerCase().trim()})
.fetch({require: true})
.tap(function(user) {
return bcrypt.compareAsync(password, user.get('encrypted_password'))
.then(function (matches) {
if (!matches) throw new InvalidPasswordError();
}
});
})
现在按类型捕获该错误并以适当的错误响应。
handler: function(request, reply) {
var email = request.payload.email;
var pwd = request.payload.password;
User.login(email, pwd).then(function(user) {
reply(user.pick('api_token'));
}).catch(User.NotFoundError, function() {
reply({error: email + ' not found'}).code(400);
}).catch(InvalidPasswordError, function() {
reply({error: 'invalid password'}).code(400);
}).catch(function(err) {
console.error(err);
});
},
我认为 Rhys van der Waerden 提供了一个很好的解决方案。但是,要弄清楚您的代码有什么问题,请考虑以下内容(来自 bluebird 规范):
getUser().tap(function(user) {
//Like in finally, if you return a promise from the handler
//the promise is awaited for before passing the original value through
return recordStatsAsync();
}).then(function(user) {
//user is the user from getUser(), not recordStatsAsync()
});
如您所见,.then
案例得到了完整的结果,.tap
的异步部分没有提供.then
的数据。
长话短说:从 .tap
更改为 .then
,你应该会很好。但是,您将获得的结果将是 true
或 false
而不是用户数据。