req.user.id 和负载 ID 的 Hapi 验证

Hapi validation for req.user.id and payload id

我在 hapi 中有简单的路由

const handler = async(request, reply) => {
  const id = Helpers.extractUserId(request)
  const payload = request.payload
  if (payload.recipient !== id) {
    // my code....
  } else {
    return reply({ success: false, message: '_id and recipient id should not match' })
    //I want to return this from routeConfig itself
  }
}

const routeConfig = {
  method: 'POST',
  path: '/requestfriend',
  config: {
    auth:'jwt',
    validate: {
      payload: {
        recipient: Joi.string().required().error(new Error('recipient is required'))
      }
    },
    handler
  }
}

我为 if (payload.recipient !== id) 设置了一个条件,这意味着登录用户的 ID 和负载接收者的 ID 相同,那么它应该抛出错误...

我不想这样做,而是想把这个条件放在 routeConfig 本身...那么有没有可以在这里使用的参数,就像 authvalidatehandler?

好吧,这取决于你想做什么......如果你试图根据 id 验证用户,我建议你检查 the relevant part of the doc

真的很容易实现:

  • 在 server.js
  • 中定义一个 validate 函数
  • 在路由配置中添加身份验证选项

如果验证函数 return false 您的端点将 return 出现 401 错误。

您可以使用 hapi route validation options 验证您的负载 这是符号。

validate: {
    payload: async (value, options) => {
    }
}

这里是解释

a validation function using the signature async function(value, options) where:

value - the request.payload object containing the request query parameters.

options - options.

if a value is returned, the value is used as the new request.payload value and the original value is stored in request.orig.payload.

Otherwise, the payload is left unchanged. If an error is thrown, the error is handled according to failAction.

这里是根据您的应用程序的示例代码,这只是一个转储示例,但我希望您能理解这里的想法。您可以在每个请求中单独验证负载、查询和参数对象。只需传递 Joi 验证器或函数来验证传入数据。

const routeConfig = {
    method: 'POST',
    path: '/requestfriend',
    config: {
        auth: 'jwt',
        validate: {
            payload: async (value, options) => {
                // extract recipient data from payload
                const {recipient} = value;
                // you can now validate your recipient
                const result = Joi.validate({recipient}, Joi.string().required().error(new Error('recipient is required')), {abortEarly: false});
                if(result.error) throw Boom.badRequest(result.error);
                // there is no request object here, you have to dig in options.context parameter
                // this is how it's look like
                // {
                //     context:
                //         {
                //             headers:
                //                 {
                //                     host: 'localhost:3009',
                //                     'user-agent': 'curl/7.54.0',
                //                     accept: '*/*',
                //                     'content-length': '13',
                //                     'content-type': 'application/x-www-form-urlencoded'
                //                 },
                //             params: {},
                //             query: {x: 'y'},
                //             auth:
                //                 {
                //                     isAuthenticated: false,
                //                     isAuthorized: false,
                //                     credentials: null,
                //                     artifacts: null,
                //                     strategy: null,
                //                     mode: null,
                //                     error: null
                //                 },
                //             app: {route: {}, request: {}}
                //         },
                //     abortEarly: false
                // }

                // let's say we got id parameters here
                const id = Helpers.extractUserId(options.context);
                if(id !== recipient) throw Boom.badRequest('_id and recipient id should not match')
            }
        },
        handler
    }
}