Passport.js本地登录与身体验证和错误处理

时间:2016-06-21 21:36:27

标签: node.js express passport.js passport-local

我需要身体验证和更好的错误处理,而无需第一个验证中间件。代码工作得很好,但我想删除第一个中间件并在第二个中间管理验证。

路由/ auth.js

router.post('/signin', function(req, res, next){

    req.checkBody('email', 'Email is required.').notEmpty();
    req.checkBody('email', 'Invalid email format.').isEmail();
    req.checkBody('password', 'Password is required.').notEmpty();
    req.checkBody('password', 'The password length must be between 8 and 100.').isLength({min: 8, max: 100});

    var err = req.validationErrors();
    if (err) {
        res.status(400).send({ success: false, error: err});
        return;
    }
    next();
});

router.post('/signin', passport.authenticate('local', { session: false }), function(req, res){
    var user = req.user;
    return res.json({success: true, user: user});
});

关于错误处理,如果用户不匹配,则错误为:

{
  "error": "Invalid email and/or password"
}

我希望如此:

{
  "success":false,
  "error": "Invalid email and/or password"
}

我该怎么做?

passport.js

passport.use(new LocalStrategy({
        usernameField: 'email',
        passwordField: 'password'
    },
    function(email, password, done) {
        User.findOne({ email: email, password: password },'-password', function (err, user) {
            if (err)return done(err);
            if(!user){
                var err = new Error('Invalid email and/or password');
                err.status = 401;
                return done(err, false);
            }

            return done(null, user);
        })
    }
));

感谢您的回复。

1 个答案:

答案 0 :(得分:2)

如果我理解正确,您希望验证发生在LocalStrategy对象的验证功能中。

在您执行此操作之前,首先需要访问req对象。为此,您需要启用策略的passReqToCallback选项:

passport.use(new LocalStrategy({
        usernameField     : 'email',
        passwordField     : 'password',
        passReqToCallback : true
    },
    function(req, email, password, done) { ... });

从那里,您可以使用与第一个中间件相同的验证码:

function(req, email, password, done) {
    req.checkBody('email', 'Email is required.').notEmpty();
    req.checkBody('email', 'Invalid email format.').isEmail();
    req.checkBody('password', 'Password is required.').notEmpty();
    req.checkBody('password', 'The password length must be between 8 and 100.').isLength({min: 8, max: 100});

    var err = req.validationErrors();
    if (err) {
      return done(err, false, { success: false, error: err});
    }
    User.findOne({...});
});

最后,您需要使用passport.authenticate()的自定义回调来处理验证结果:

router.post('/signin', function(req, res, next) {
  passport.authenticate('local', { session : false }, function(err, user, info) {
    if (err) return next(err);
    if (! user) {
      return res.status(400).json(info);
    }
    return res.json({ success : true, user : req.user});
  })(req, res, next);
});

回调的info参数映射到验证处理程序中done()回调的第三个参数。

需要注意的一点是,如果请求正文中的emailpassword为空,Passport将不会调用本地策略处理程序,这会使notEmpty验证失败。