gpt4 book ai didi

javascript - 尽管参数可用,但模式验证失败

转载 作者:搜寻专家 更新时间:2023-10-31 23:50:08 24 4
gpt4 key购买 nike

我创建了一个 REST api 并希望在调用 Controller 逻辑之前验证主体和参数。对于验证,我使用 Joi ( https://www.npmjs.com/package/joi )。

假设我有一个带有一个 url 参数和一些主体变量的路由。 params 对象包含此 url 参数,但 Joi 仍返回 400。详细消息是

"userId" is required

我试图创建一个显示我的代码的简约示例。要重现错误,请创建 app.js 文件

const express = require('express');
const bodyParser = require('body-parser');
const morgan = require('morgan');
const cors = require('cors');

const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());

app.use('/users', require('./routes/users.js'));

app.listen(3000);

由于每个验证都失败,因此只需要一条路径来测试它。使用以下内容创建 users.js

const express = require('express');
const router = express.Router();

const usersController = require('../controllers/users.js');
const usersControllerPolicy = require('../policies/users.js');

router.get('/:userId', usersControllerPolicy.getUserById, usersController.getUserById);

module.exports = router;

还有这个users.js Controller 文件

exports.getUserById = async (req, res, next) => {
const { userId } = req.params;
return res.status(200).json("everything is fine");
};

当涉及到策略时,我创建了 users.js 策略,它将所需的模式添加到中间件

const joi = require('joi');

const schemaValidation = require('../middleware/schemaValidation.js');

module.exports = {
getUserById: (req, res, next) => {
schemaValidation({
params: {
userId: joi.string().guid().required()
},
body: {}
}, req, res, next);
}
}

然后架构由我的 schemaValidation.js

验证
const joi = require('joi');

module.exports = (schema, req, res, next) => {
const { error } = joi.validate(req, schema);

if (error)
return res.status(400).json("something went wrong");

next(); // execute the controller logic
}

如您所见,我传入了整个 req 对象。我这样做是因为有时我必须验证主体和参数。 Joi 未找到 url 参数 userId,因此我返回状态代码 400。

如何修复我的中间件验证以验证 req 对象中的两个对象?

最佳答案

实际上 Joi 可以访问 userId 并且可以正确验证它与否,原因如下:

// replace this
const { error } = joi.validate(req, schema);
// by this
console.log(req.params.userId);
const { error } = joi.validate(req, schema);
console.log(error.toString());

访问 localhost:3000/users/10 时的控制台输出:

10
ValidationError: child "params" fails because [child "userId" fails because ["userId" must be a valid GUID]]

并且在访问 URL 时在参数中包含有效的 GUID,例如 ``:

ad3756ae-2661-4d8c-aeda-dd51deef5ea9
ValidationError: "_readableState" is not allowed. "readable" is not allowed. "_events" is not allowed. "_eventsCount" is not allowed. "_maxListeners" is not allowed. "socket" is not allowed. "connection" is not allowed. "httpVersionMajor" is not allowed. "httpVersionMinor" is not allowed. "httpVersion" is not allowed. "complete" is not allowed. "headers" is not allowed. "rawHeaders" is not allowed. "trailers" is not allowed. "rawTrailers" is not allowed. "aborted" is not allowed. "upgrade" is not allowed. "url" is not allowed. "method" is not allowed. "statusCode" is not allowed. "statusMessage" is not allowed. "client" is not allowed. "_consuming" is not allowed. "_dumped" is not allowed. "next" is not allowed. "baseUrl" is not allowed. "originalUrl" is not allowed. "_parsedUrl" is not allowed. "query" is not allowed. "res" is not allowed. "route" is not allowed

因此 Joi 可以访问它需要的一切并按预期工作。 🚀


那么为什么会出现 400 错误呢?

好吧,正如在控制台中所记录的那样,Joi 未能通过 req 的验证。这是因为,默认情况下,Joi 不接受对象中的未知参数。您可以使用 .unknown(true) 更改此设置,即使包含未知参数,它也会验证对象。

因此,在您的情况下,您应该将 policies/users.js 的代码替换为以下代码:

const joi = require('joi');

const schemaValidation = require('../middleware/schemaValidation.js');

module.exports = {
getUserById: (req, res, next) => {

// properly defines a schema with optional parameters
const schema = joi.object({
params: joi.object({
userId: joi.string().guid().required()
}).unknown(true),
}).unknown(true);

schemaValidation(schema, req, res, next);
}
}

现在,当您再次访问包含有效 GUID(如 http://localhost:3000/users/ad3756ae-2661-4d8c-aeda-dd51deef5ea9)的 URL 时,一切都会按预期发生并且服务器正在发送 ""everything is fine"!🎉

关于javascript - 尽管参数可用,但模式验证失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55307103/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com