使用express-validator实现密码验证时请求阻塞问题求助
Fixing Password Confirmation Validation with express-validator
Let's break down what went wrong with your implementations and fix them step by step.
Why Your First Approach Failed
In your initial code, you tried to use res.end() directly inside the custom validator. The problem here is:
- The
customvalidator callback from express-validator doesn't receive theresobject as a parameter. - Even if it did, you shouldn't terminate the request directly in the validator. Express-validator is designed to collect validation errors, which you then check later to decide how to respond.
Why Your Second Approach Caused Blocking
Your standalone middleware had two critical issues:
- You returned the
body()validation chain instead of executing it. Thebody()function creates a validator, but doesn't run it automatically unless you're using it in the route array. - You called
next()unconditionally inside thecustomcallback, regardless of whether validation passed. This meant even when passwords didn't match, the request tried to proceed to the controller, leading to unexpected behavior or blocking.
Correct Implementation 1: Inline Validation with Error Handling
This is the simplest way to use express-validator for your use case. We'll define the validator in the route, then add a middleware to check for validation errors before hitting your controller:
const { body, validationResult } = require('express-validator'); const auth = require('../controllers/auth'); router.post('/signup', [ // Validate that confirmpassword matches password body('confirmpassword').custom((value, { req }) => { if (value !== req.body.password) { // Throw an error to mark validation as failed throw new Error('Passwords do not match'); } // Return true to confirm validation passed return true; }) ], (req, res, next) => { // Check for any validation errors const errors = validationResult(req); if (!errors.isEmpty()) { // Send a 400 response with the error message return res.status(400).send(errors.array()[0].msg); // Or use JSON for API responses: // return res.status(400).json({ errors: errors.array() }); } // No errors? Proceed to the signup controller next(); }, auth.signUp);
Correct Implementation 2: Standalone Validation Middleware
If you want to reuse this validation logic across multiple routes, here's how to properly wrap it in a middleware:
// middleware/validatePassword.js const { body, validationResult } = require('express-validator'); const validatePassword = async (req, res, next) => { // Run the validation chain manually await body('confirmpassword') .custom((value, { req }) => { if (value !== req.body.password) { throw new Error("Verify password and password didn't match"); } return true; }) .run(req); // Execute the validator against the request // Check if any errors were found const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).send(errors.array()[0].msg); } // Validation passed, move to the next middleware/controller next(); }; module.exports = validatePassword;
Then use it in your route like this:
const auth = require('../controllers/auth'); const validatePassword = require('../middleware/validatePassword'); router.post('/signup', validatePassword, auth.signUp);
Key Takeaways
- Always use
throw new Error()in express-validator callbacks to mark validation failures. - Use
validationResult(req)to retrieve errors and respond appropriately before proceeding to your controller. - When creating standalone validation middleware, remember to manually run the validator with
.run(req)and wait for it to complete.
内容的提问来源于stack exchange,提问作者mdvenkatesh nuhk
相关产品推荐
相关产品推荐

