如何在MVC架构的Node.js应用中高效编写与放置中间件
Node.js MVC架构下认证中间件的放置方案
身份认证类中间件的最优放置位置是路由层,放在路由匹配规则之后、控制器处理函数之前注入即可,完全符合MVC架构的职责拆分原则。
为什么放在路由层?
- 符合各层职责边界:路由层的核心作用是管理请求路径、请求方法、准入规则、请求分发,认证属于请求准入逻辑,不属于业务逻辑(控制器层)、也不属于数据操作逻辑(服务层/模型层),放在路由层不会造成职责越界。
- 灵活度更高:可以按需给单个路由、路由组、全局路由挂载,不需要登录就能访问的公开接口(比如登录、注册、公开数据查询接口)可以不用挂载,无需修改业务层代码。
- 避免代码冗余:如果把认证逻辑写在控制器里,每个需要鉴权的控制器都要重复编写校验逻辑,容易遗漏也不好维护。
具体实现示例
第一步:单独管理中间件
新建middlewares/auth.js文件存放你的认证中间件,所有通用中间件都放在middlewares目录下统一维护:
// middlewares/auth.js 认证中间件示例 const jwt = require('jsonwebtoken') module.exports = async (req, res, next) => { try { // 从请求头提取token const token = req.headers.authorization?.split(' ')[1] if (!token) return res.status(401).send('未提供身份认证凭证') // 校验token有效性 const decodedUser = jwt.verify(token, process.env.JWT_SECRET_KEY) // 校验通过后将用户信息挂载到req对象,后续控制器可直接调用 req.user = decodedUser // 放行到下一个处理逻辑(控制器) next() } catch (error) { return res.status(401).send('身份凭证无效或已过期') } }
第二步:路由层挂载中间件
在路由文件中导入中间件,放在控制器函数之前即可:
// User routes 路由文件修改示例 const auth = require('../middlewares/auth') const courseController = require('../controllers/courseController') // 单个路由挂载认证中间件 router.get('/fetchAllCourses/:schoolId', auth, courseController.apiFetchCourses); // 批量给路由组挂载 router.use('/api/private', auth) // 下方所有/api/private前缀的接口都会自动走认证中间件,无需单独配置 router.get('/api/private/my-courses', courseController.getMyCourses) router.post('/api/private/course', courseController.createCourse)
额外注意
不要将认证逻辑放在控制器层或服务层:
- 控制器层只负责处理请求参数、调用服务、返回响应,不应该耦合通用的准入逻辑
- 服务层只负责纯业务数据处理,和HTTP请求解耦,后续如果需要复用服务逻辑给内部其他调用方(比如定时任务、RPC接口)也不会受到鉴权逻辑的影响
你现有代码里有两处笔误可以修正:
- 控制器导出代码拼写错误:
module.exprots改为module.exports - 服务层没有导入
schools模型,需要补充const schools = require('../models/School')
内容的提问来源于stack exchange,提问作者Prasoon Shukla
相关产品推荐
相关产品推荐

