如何在Joi中添加自定义验证器功能?

问题描述 投票:0回答:4

我有 Joi 模式,想要添加一个自定义验证器来验证数据,而默认 Joi 验证器无法实现这一点。

目前我使用的是Joi 16.1.7版本

const method = (value, helpers) => {
  // for example if the username value is (something) then it will throw an 
  // error with the following message but it throws an error inside (value) 
  // object without error message. It should throw error inside the (error) 
  // object with a proper error message
        
  if (value === "something") {
    return new Error("something is not allowed as username");
  }

  return value; // Return the value unchanged
};
        
const createProfileSchema = Joi.object().keys({
  username: Joi.string()
    .required()
    .trim()
    .empty()
    .min(5)
    .max(20)
    .lowercase()
    .custom(method, "custom validation")
});
        
const { error, value } = createProfileSchema.validate({
  username: "something" 
});
        
console.log(value); // returns {username: Error}
console.log(error); // returns undefined

但是我无法以正确的方式实现它。我读过 Joi 文档,但对我来说似乎有点令人困惑。谁能帮我解答一下吗?

javascript node.js validation express joi
4个回答
44
投票
const Joi = require('@hapi/joi');
    
Joi.object({
  password: Joi
    .string()
    .custom((value, helper) => {
      if (value.length < 8) {
        return helper.message("Password must be at least 8 characters long");
      }

      return true;
    })
}).validate({
    password: '1234'
});

36
投票

你的自定义方法必须是这样的:

const method = (value, helpers) => {
  // for example if the username value is (something) then it will throw an 
  // error with the following message but it throws an error inside (value) 
  // object without error message. It should throw error inside the (error) 
  // object with a proper error message

  if (value === "something") {
    return helpers.error("any.invalid");
  }

  return value; // Return the value unchanged
};

文档:

https://github.com/hapijs/joi/blob/master/API.md#anycustommethod-description

价值输出:

{ username: 'something' }

错误输出:

[Error [ValidationError]: "username" contains an invalid value] {
  _original: { username: 'something' },
  details: [
    {
      message: '"username" contains an invalid value',
      path: [Array],
      type: 'any.invalid',
      context: [Object]
    }
  ]
}

2
投票

这就是我验证代码的方式,看看它并尝试格式化你的代码

const busInput = (req) => {
  const schema = Joi.object().keys({
    routId: Joi.number().integer().required().min(1)
      .max(150),
    bus_plate: Joi.string().required().min(5),
    currentLocation: Joi.string().required().custom((value, helper) => {
      const coordinates = req.body.currentLocation.split(',');
      const lat = coordinates[0].trim();
      const long = coordinates[1].trim();
      const valRegex = /-?\d/;
      if (!valRegex.test(lat)) {
        return helper.message('Laltitude must be numbers');
      }
      if (!valRegex.test(long)) {
        return helper.message('Longitude must be numbers');
      }
    }),
    bus_status: Joi.string().required().valid('active', 'inactive'),
  });
  return schema.validate(req.body);
};

0
投票

最近遇到了同样的问题,希望这有帮助。

//joi object schema     
password: Joi.custom(validatePassword, "validate password").required(),


// custom validator with custom message
// custom.validation.ts

import { CustomHelpers } from "joi";

const validatePassword = (value: string, helpers: CustomHelpers) => {
  if (value.length < 6) {
    return helpers.message({
      custom: "Password must have at least 6 characters.",
    });
  }

  if (!value.match(/\d/) || !value.match(/[a-zA-Z]/)) {
    return helpers.message({
      custom: "Password must contain at least 1 letter and 1 number.",
    });
  }

  return value;
};

export { validatePassword };
© www.soinside.com 2019 - 2024. All rights reserved.