使用 express-validator 检查输入是用户名还是电子邮件

Using express-validator to check if input is a username or email

我正在尝试验证登录请求,它接受可以是电子邮件或用户名的用户名和密码。我如何使用 Express-Validator 执行此操作?

我正在阅读文档,验证器的工作方式是您必须将数据作为第二个参数传递。 我不确定如何检查它是否也是用户名或密码。

router.post("/", (req, res) => {
    const { nickname, password } = req.body;
    // Create a new object based on email or username
    const login = {};
    if (nickname.indexOf('@') === -1) {
        login.nickname = nickname;
    } else {
        login.email = nickname;
    }
    login.password = password;
    // JWT Sign...
});

有了验证器,我也想看看是不是

尝试

router.post("/", (req, res) => {
    const { nickname, password } = req.body;
    // Create a new object based on email or username
    const login = {};
    if (nickname.indexOf('@') === -1) {
        check('nickname').isLength({ 'min': 3 });
        login.nickname = nickname;
    } else {
        check('nickname').isEmail();
        login.email = nickname;
    }
    login.password = password;
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(422).json({ errors: errors.array() });
    }
});

似乎验证器不起作用。

我建议你使用 Joi 验证器 (npm install joi --save)

const Joi = require('joi');

const validateRequest = (schema) => async (req, res, next) => {
    const { error } = Joi.validate(req.body, schema);

    if (error) {  
      throw new Error(error);
    }

    return next();
  };

const validationSchema =  Joi.object().keys({
    nickname:  [Joi.string().email(), Joi.string().min(3)],
    password: Joi.string().required(),
  }),

router.post('/', validateRequest(validationSchema), (req, res) => 
// rest of your code

但是您的代码的快速修复方法是将变量 nickname 传递给 check 而不是字符串:

    check(nickname).isLength({ 'min': 3 });
    check(nickname).isEmail();

您可以使用 oneOf 来验证用户名或电子邮件。这是一个例子:

const util = require('util');
const { validator } = require('express-validator');
const { check, oneOf, validationResult } = require('express-validator/check');


const validation = [
    oneOf([
        check('nickname')
          .exists()
          .withMessage('nickname is required')
          .isLength({ min: 3 })
          .withMessage('wrong nickname length'),

        check('nickname')
          .exists()
          .withMessage('nickname is required')
          .isEmail()
          .withMessage('nickname not valid'),
    ]),
    check('password')
        .exists()
        .withMessage('password is required')
];

function handleValidationErrors(req, res, next) {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    console.log(util.inspect(errors.array()));
    return res.status(422).json({ errors: errors.array() });
  }

  next();
};

router
  .post('/', validation, handleValidationErrors,
    (req, res) => {
      const isEmail = validator.isEmail(req.body.nickname);

      res.status(200).json({ isEmail });
    });

nickname 可以是长度大于 3 的字符串或电子邮件。始终需要密码。验证器数组作为中间件数组传递给 router.post()handleValidationErrors() 只是一个辅助函数。实际逻辑中可以有相同的逻辑,也可以用try-catch。

我在主回调中使用 isEmail() 来检查它是用户名还是电子邮件。然后我将其发送到回复中。您可以根据自己的喜好使用 isEmail

试试这个,

npm install validator

npm install express-validator

然后

const {check, oneOf } = require('express-validator')
const validator = require('validator')

在你的验证函数中试试这个,

oneOf([
  check('nickname').isEmail(),
  check('nickname').not().isEmpty().isString().custom((value, {req})=>{
     if(!validator.isEmail(value)){
       req.body.flag = true
       // you can handler your req.body here .... 

     }
     return true
  })
]