验证Hapi.js和Bookshelf.js问题

时间:2015-07-31 03:13:07

标签: javascript hapijs bookshelf.js

我正在关注他们在bookshelf.js(http://bookshelfjs.org/#Model)网站上提供的login示例,但由于某种原因,无论我是否提交了错误密码,我的代码都会返回200响应

这是我的路线:

    {
        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通过比较好的请求和坏请求上的密码并且那段代码正常工作来响应,但就像我说的那样,即使我提交了一个错误的密码,也会返回用户

2 个答案:

答案 0 :(得分:2)

我认为Rhys van der Waerden提供了一个很好的解决方案。但是,要弄清楚代码有什么问题,请考虑一下(来自蓝鸟规范):

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,你应该做得很好。但是,您获得的结果将是truefalse,而不是用户数据。

答案 1 :(得分:1)

是的,这里的文档是错误的。

你没有对compareAsync的结果做任何事情。它返回一个解析为bool的承诺(docs here)。

所以你可能想做这样的事情:

在某处创建错误类。我正在使用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);
  });
},