如何在Express中将POST路由/api/auth/confirmation作为/users路由的中间件
解决思路:复用路由逻辑作为中间件而非重定向
你之前遇到的问题核心在于**res.redirect() 默认会发起 GET 请求**,但你的 /api/auth/confirmation 是 POST 路由,所以会出现 Cannot GET 错误;另外,res.redirect() 已经结束了响应周期,后续的 next() 也不会生效。
要实现「把 /api/auth/confirmation 的逻辑作为 /api/users 的中间件,且禁止直接访问前者」的需求,最佳方式是把目标路由的校验和业务逻辑抽成独立的可复用函数,而不是通过重定向跳转。下面是具体实现步骤:
步骤1:抽离/auth/confirmation的逻辑到独立函数
修改 auth/auth.js,把校验规则和处理逻辑分别导出,不再直接绑定到路由上:
const { check, validationResult } = require('express-validator'); // 导出校验规则数组 exports.confirmationValidation = [ check('name', 'Name is required').not().isEmpty(), check('email', 'Enter valid email').isEmail(), ]; // 导出确认逻辑的处理函数(作为中间件) exports.handleConfirmation = (req, res, next) => { // 先处理校验结果 const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } // 原来的 /confirmation 路由里的业务逻辑 console.log('confirm route'); // 这里可以添加你的确认逻辑,比如验证邮箱、生成令牌等 // 如果逻辑执行成功,调用 next() 进入下一个中间件(即 /api/users 的逻辑) next(); }; // 删掉原来的 POST /confirmation 路由,或者注释掉,禁止直接访问 // router.post('/confirmation', exports.confirmationValidation, exports.handleConfirmation);
步骤2:在/users.js中复用这些中间件
修改 users.js,引入 auth 模块里的校验和处理函数,作为 POST /api/users 的前置中间件:
const express = require('express'); const router = express.Router(); const auth = require('./auth/auth'); // 路径根据你的项目结构调整 // 自定义的临时中间件(保留你的 console.log) const checkk = (req, res, next) => { console.log('middleware'); next(); // 这里不需要 redirect,直接传递请求到下一个中间件 }; router.post('/', checkk, // 你的自定义中间件 auth.confirmationValidation, // 复用确认路由的校验规则 auth.handleConfirmation, // 复用确认路由的处理逻辑 async (req, res) => { console.log('user route'); res.send("user route"); } ); module.exports = router;
为什么这样可行?
- 请求会按顺序经过中间件链:
checkk→ 校验规则 →handleConfirmation→ 最终的用户路由逻辑,完全符合你期望的输出顺序:middleware→confirm route→user route。 - 原来的
/api/auth/confirmation路由被移除,用户无法直接访问,只能通过/api/users触发这部分逻辑。 - 保留了
express-validator的校验逻辑,校验不通过时会直接返回错误响应,不会进入后续的中间件。
额外注意事项
如果你的 handleConfirmation 里有异步操作(比如数据库查询),记得把它改成 async 函数,并在调用异步方法时加 await,同时确保捕获错误:
exports.handleConfirmation = async (req, res, next) => { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } try { // 异步业务逻辑,比如: // await User.updateOne({ email: req.body.email }, { confirmed: true }); console.log('confirm route'); next(); } catch (err) { res.status(500).send('Server Error'); } };
内容的提问来源于stack exchange,提问作者Mahesh Jaganiya
相关产品推荐
相关产品推荐

