如何使用护照和快递显示自定义错误消息

时间:2016-02-17 09:38:06

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

我在注册用户时检查电子邮件是否已存在。如果用户已经存在,则传递错误消息"电子邮件已存在"。但在前端它显示" Unauthorized"错误401.我想传递错误消息,我从后端传递到前端,但它传递了默认消息。下面是我如何检查用户是否已经存在并发送错误消息

exports.register = new LocalStrategy({
    usernameField: 'email',
    passReqToCallback: true
}, function(req, email, password, done,res) {
    var newUser = new User({
        email: email,
        password: password,
        name: req.body.fname
    });
    var searchUser = {
        email: email
    };
    User.findOne(searchUser, function(err, user) {
        if (err) return done(err);
        console.log("err "+err);

        if (user) {
            return done(null, false, {
                message: "email already exists"
            });
        }
        newUser.save(function(err) {
        console.log("newUser "+newUser);
            done(null, newUser);
        })
    });
});

我使用护照进行身份验证,

authRouter.post('/signup', passport.authenticate('local-register'),function(req, res) {
    createSendToken(req.user, res);
});

错误消息不是我传递给前端的消息。它显示未经授权的错误,这是默认错误。当我在前端的控制台中打印错误消息时,它显示,

Object {data: "Unauthorized", status: 401, config: Object, statusText: "Unauthorized"}

4 个答案:

答案 0 :(得分:7)

您没有在前端说出您想要的输出,但我猜您希望data成为您在message中设置的LocalStrategy

这是一种方法:

authRouter.post('/signup', function(req, res, next) {
  passport.authenticate('local-register', function(err, user, info) {
    if (err) { return next(err); }
    if (!user) { 
        res.status(401);
        res.end(info.message);
        return;
    }
    createSendToken(req.user, res);
  })(req, res, next);
});

答案 1 :(得分:1)

您可以利用passport中的passReqToCallback: true

启用此选项后, req 将作为第一个参数传递到验证回调。

还可以利用flash messages

这是使用方法的基本示例,

// your strategy
passport.use(new LocalStrategy({
    passReqToCallback: true
  },
    (req, username, password, done) => {
      User.findOne({ username: username }, (err, user) => {
        if (err) done(err)
        if (!user) {
          console.log('user does not exists')
          return done(null, false, req.flash('message', 'User does not exist' ))
        } else {
          console.log('user exists')
          return done(null, user, req.flash('message', 'User exist'))
        }
      })
    }
  ))

// your GET login
router.get("/login", (req, res) => {
  var message = req.flash('message')
  res.render("pages/login", { message })
})

答案 2 :(得分:0)

如果您使用passReqToCallback = true,则可以像发送

一样发送
if (!isMatch) { return done({ message: 'Incorrect password' }); }

答案 3 :(得分:0)

如其他答案所述,您可以手动检查info参数,然后根据该参数返回您自己的消息:

// ❌ MESSY ❌
authRouter.post('/signup', function(req, res, next) {
    passport.authenticate('local-register', function(err, user, info) {
        if(info.name === 'UserExistsError' ) {
            return done(null, false, {
                message: "Email already exists"
            });
        } else if (info.name === 'IncorrectUsernameError') {
          return done(null, false, {
              message: "Email does not exist"
          });
        } else if(....

但是很多的更简洁的方法是在创建Account猫鼬模型时仅指定自定义错误消息:

var Account = new Schema({
    ...
});

var options = {
    errorMessages: {
        UserExistsError: 'Email already exists',
        IncorrectUsernameError: 'Email does not exist',
        IncorrectPasswordError: ...
    }
};

Account.plugin(passportLocalMongoose, options);

然后,在您的注册路线中,您只需将info.message返回给用户即可。

// ✨ CLEAN ✨
authRouter.post('/signup', function(req, res, next) {
    passport.authenticate('local-register', function(err, user, info) {
        return done(null, false, {
            message: info.message
        });
    });
});