最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - validate the whole request object with joi - Stack Overflow

programmeradmin3浏览0评论

I created a middleware that validates the request input before calling the controller logic.

Let's say I have a "get user by id" - route

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

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

// other routes

Before executing the controller I use the policy to validate the params and the body. My policy module for users is

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

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

    // other routes
}

The userId is a route parameter, not a variable within the body. The schemaValidation middleware validates the given schema and calls next() or sends a 400 response.

const joi = require('joi');
const requestResponder = require('../helpers/requestResponder.js');

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

    if (error)
        return requestResponder.sendBadRequestError(res);

    next();
}

When I call this route with /users/137eaa6f-75c2-46f0-ba7c-c196fbfa367f I get this error

message: '"userId" is required'

but the validation should be fine. I checked the validation joi.validate(req, schema) by logging req.params and the userId is available. What am I missing?


Edit:

I know I could validate req.params but what if I want to update a user? I would have to validate the params (userId) and the body (name, age, ...)

I created a middleware that validates the request input before calling the controller logic.

Let's say I have a "get user by id" - route

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

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

// other routes

Before executing the controller I use the policy to validate the params and the body. My policy module for users is

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

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

    // other routes
}

The userId is a route parameter, not a variable within the body. The schemaValidation middleware validates the given schema and calls next() or sends a 400 response.

const joi = require('joi');
const requestResponder = require('../helpers/requestResponder.js');

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

    if (error)
        return requestResponder.sendBadRequestError(res);

    next();
}

When I call this route with /users/137eaa6f-75c2-46f0-ba7c-c196fbfa367f I get this error

message: '"userId" is required'

but the validation should be fine. I checked the validation joi.validate(req, schema) by logging req.params and the userId is available. What am I missing?


Edit:

I know I could validate req.params but what if I want to update a user? I would have to validate the params (userId) and the body (name, age, ...)

Share Improve this question edited Mar 20, 2019 at 16:12 asked Mar 20, 2019 at 12:50 user9945420user9945420 2
  • If userID is available in req.params then should you validate req.params? e.g. joi.validate(req.params, schema) – Igor Commented Mar 20, 2019 at 15:41
  • @Igor yes but I need to validate the params and the body. I pass in the userId as a parameter but there might be variables to validate in the body too. – user9945420 Commented Mar 20, 2019 at 15:57
Add a ment  | 

1 Answer 1

Reset to default 6

Your joi validation schema should reflect req object structure, that should work:

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

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

    // other routes
}

When you need to validate both body and params:

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

const paramsValidation = joi.object({
    userId: joi.string().guid().required()
}).unknown(true);

const bodyValidation = joi.object({
    name: joi.string().required()
}).unknown(true);

module.exports = {
    getUserById: (req, res, next) => {
        schemaValidation(joi.object({
            params: paramsValidation,
            body: bodyValidation
        }).unknown(true), req, res, next);
    }

    // other routes
}

But i would rather prefer to validate them separately with 3 joi schemas (body, params, query) e.g. how it done here https://www.npmjs./package/express-joi-validation#validation-ordering

发布评论

评论列表(0)

  1. 暂无评论