【问题标题】:.when() in joi validation, to validate one key based on another key.when() 在 joi 验证中,根据另一个键验证一个键
【发布时间】:2019-06-04 08:06:33
【问题描述】:

管理员将创建用户,并在此过程中输入一些随机字符串作为密码。当管理员编辑现有用户时,他不需要输入任何密码,除非他想更改它。如果管理员不输入任何密码,则使用旧密码。

所以我尝试使用.when() 来处理这种情况。当payload中存在_id(只有当用户存在时才有可能),那么我们应该将密码字段设为可选,否则需要密码。

这是我的 Joi 验证

const usersJoiSchema = Joi.object({
  _id: Joi.string().optional(),
  firstName: Joi.string().required(),
  lastName: Joi.string().required(),
  email: Joi.string().required(),
  password: Joi.string().when('_id', { is: Joi.exist(), then: Joi.optional(), otherwise: Joi.required() })
})

Joi 在这种情况下有一个方法.when。但出于某种奇怪的原因,它给了我

{"statusCode":500,"error":"Internal Server Error","message":"An internal server error occurred"}

作为 api 的响应,服务器控制台中没有任何内容。 我尝试比较_id 的字符串长度而不是exists(),我也尝试过

password: Joi.string().when('_id', { is: Joi.string().required(), then: Joi.string().optional(), otherwise: Joi.string().required() }),

password: Joi.string().when('_id', { is: Joi.string(), then: Joi.string().optional(), otherwise: Joi.string().required() }),

对于密码密钥,但仍然是同样的问题。

如果有人对此问题有任何想法,请帮助我。

【问题讨论】:

  • 500 错误毫无意义。您的应用程序日志中的错误是什么?
  • 日志中没有错误,正如我在上面的描述中提到的。

标签: node.js validation schema hapijs joi


【解决方案1】:

好吧,我创建了一个简单的测试,所有条件都根据您的要求通过。 我相信您的代码中还有其他内容会发生该错误。 这是我的测试代码,请看一下。

const Lab = require('lab');
const lab = exports.lab = Lab.script();
const describe = lab.describe;
const it = lab.it;
const expect = require('code').expect;
const Joi = require('joi');

const usersJoiSchema = Joi.object({
    _id: Joi.string().optional(),
    firstName: Joi.string().required(),
    lastName: Joi.string().required(),
    email: Joi.string().required(),
    password: Joi.string().when('_id', {is: Joi.exist(), then: Joi.optional(), otherwise: Joi.required()})
});

describe('Validator usersJoiSchema checks', () => {

    it('It should save new user without id', () => {
        const result = Joi.validate({
            firstName: "Hello",
            lastName: "World",
            email: "hello@world.com",
            password: "123456"
        }, usersJoiSchema, {abortEarly: false});
        expect(result.error).to.null();
        expect(result.error).to.not.exist();
    });

    it('It should update user without password field when id included', () => {
        const result = Joi.validate({
            _id: "some-id-string-here",
            firstName: "Hello",
            lastName: "World",
            email: "hello@world.com",
        }, usersJoiSchema, {abortEarly: false});
        expect(result.error).to.null();
        expect(result.error).to.not.exist();
    });


    it('It should fail when id is empty and no password provided', () => {
        const result = Joi.validate({
            firstName: "Hello",
            lastName: "World",
            email: "hello@world.com",
        }, usersJoiSchema, {abortEarly: false});
        expect(result.error).to.not.null();
        expect(result.error).to.exist();
    });
    it('It should fail when id is empty and password is also empty', () => {
        const result = Joi.validate({
            firstName: "Hello",
            lastName: "World",
            email: "hello@world.com",
            password: "",
        }, usersJoiSchema, {abortEarly: false});
        expect(result.error).to.not.null();
        expect(result.error).to.exist();
    });
});

这里是测试命令

> lab --coverage-exclude test/data -m 5000n -a code -P "simple" "test/validators"

  ....

4 tests complete
Test duration: 8 ms
Assertions count: 8 (verbosity: 2.00)
No global variable leaks detected

【讨论】:

  • 感谢您的回答。我仍然不明白为什么它给我 500 错误。我正在使用完全相同的架构。并且路由或控制器中没有与架构验证相关的逻辑。
【解决方案2】:
  _id: Joi.string(),
  password: Joi.string().when("_id", {
     is: Joi.exist(),
     then: Joi.required()
  })

通过上述,Joi 将确保只要 _id 存在就需要密码

【讨论】:

    猜你喜欢
    • 2019-07-08
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 2019-10-18
    • 1970-01-01
    • 2020-05-30
    • 2017-08-05
    • 2019-03-23
    相关资源
    最近更新 更多