Que*_*n3r 5 javascript node.js express joi
我创建了一个 REST api 并希望在调用控制器逻辑之前验证主体和参数。对于验证,我使用Joi ( https://www.npmjs.com/package/joi )。
假设我有一个带有一个 url 参数和一些 body 变量的路由。该params对象包含此 url 参数,但 Joi 仍返回一个400. 详细信息是
“用户 ID”是必需的
我试图创建一个显示我的代码的简约示例。要重现错误,请创建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);
Run Code Online (Sandbox Code Playgroud)
由于每次验证都失败这一事实,因此只需要一条路线来对其进行测试。使用以下内容创建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;
Run Code Online (Sandbox Code Playgroud)
而这个users.js控制器文件
exports.getUserById = async (req, res, next) => {
const { userId } = req.params;
return res.status(200).json("everything is fine");
};
Run Code Online (Sandbox Code Playgroud)
当涉及到策略时,我创建了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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后模式被我的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
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我传入了整个req对象。我这样做是因为有时我必须验证主体和参数。userIdJoi 没有找到url 参数,所以我返回了 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());
Run Code Online (Sandbox Code Playgroud)
访问时控制台输出localhost:3000/users/10:
10
ValidationError: child "params" fails because [child "userId" fails because ["userId" must be a valid GUID]]
Run Code Online (Sandbox Code Playgroud)
并且在访问参数中包含有效 GUID 的 URL 时,例如``:
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
Run Code Online (Sandbox Code Playgroud)
因此 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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当您再次访问包含有效 GUID 的 URL(例如http://localhost:3000/users/ad3756ae-2661-4d8c-aeda-dd51deef5ea9)时,一切都会按预期发生并由""everything is fine"服务器发送!
| 归档时间: |
|
| 查看次数: |
1479 次 |
| 最近记录: |