如何在 Hapi.js 中链接登录门?

How to chain login gates in Hapi.js?

我正在尝试验证通过 POST 请求发送的 JSON。我正在为 hapijs 使用 JOI 验证器。 JSON 不能同时拥有密码和访问令牌,但如果用户是来宾,则忽略此检查。

validate: {
      payload: Joi.object({
        isGuest: Joi.boolean().required(),
        username: Joi.string().when('isGuest', { is: false, then: Joi.required() }),
        password: Joi.string().alphanum(),
        accessToken: Joi.string().alphanum(),
      }).options({ allowUnknown: true }).xor('password', 'accessToken'),
    },

我尝试实现的逻辑看起来像这样。

OR('isGuest', XOR(AND('username','password'), 'accessToken'))

我不知道如何使用可用的工具来实现它。

您可以使用without

const schema = Joi.object().keys({
  isGuest: Joi.boolean(),
  password: Joi.string().alphanum(),
  accessToken: Joi.string().alphanum(),
}).without('isGuest', ['password', 'accessToken'])
  .without('password', 'accessToken');

这是测试用例

const object1 = { isGuest: true }
console.log(Joi.validate(object1, schema)); // pass

const object2 = { password: 'asdfads' }
console.log(Joi.validate(object2, schema)); // pass

const object3 = { accessToken: 'asdfads' }
console.log(Joi.validate(object3, schema)); // pass

const object4 = { isGuest: true, password: "asdf" }
console.log(Joi.validate(object4, schema)); // fail

const object5 = { isGuest: true, accessToken: "asdf" }
console.log(Joi.validate(object5, schema)); // fail

const object6 = { password: "asdf", accessToken: "asdf" }
console.log(Joi.validate(object6, schema)); // fail

如果您也对值感兴趣,可以使用此架构

const schema = Joi.object().keys({
  isGuest: Joi.boolean(),
  password: Joi.string().alphanum(),
  accessToken: Joi.string().alphanum(),
}).when(Joi.object({
  isGuest: Joi.boolean().required().valid(true),
  password: Joi.string().alphanum().optional(),
  accessToken: Joi.string().alphanum().optional(),
}), {
    then: Joi.object({
      password: Joi.string().alphanum().optional(),
      accessToken: Joi.string().alphanum().optional(),
    }),
    otherwise: Joi.object({
      password: Joi.string().alphanum(),
      accessToken: Joi.string().alphanum(),
    }).xor('password', 'accessToken'),
  });

const object1 = { isGuest: true }
console.log(Joi.validate(object1, schema)); // pass

const object4 = { isGuest: true, password: "asdf" }
console.log(Joi.validate(object4, schema)); // pass

const object5 = { isGuest: true, accessToken: "asdf" }
console.log(Joi.validate(object5, schema)); // pass

const object7 = { isGuest: true, password: "abc", accessToken: "1234" }
console.log(Joi.validate(object7, schema)); // pass

const object2 = { isGuest: false, password: 'asdfads' }
console.log(Joi.validate(object2, schema)); // pass

const object31 = { isGuest: false, accessToken: 'asdfads' }
console.log(Joi.validate(object31, schema)); // pass

const object21 = { password: 'asdfads' }
console.log(Joi.validate(object21, schema)); // pass

const object3 = { accessToken: 'asdfads' }
console.log(Joi.validate(object3, schema)); // pass

console.log('Failure cases');

const object11 = { isGuest: false }
console.log(Joi.validate(object11, schema)); // fail

const object6 = { isGuest: false, password: "asdf", accessToken: "asdf" }
console.log(Joi.validate(object6, schema)); // fail