在使用控制器的NodeJS项目中如何使用中间件及限定其作用于特定请求
问题1:在使用控制器的NodeJS项目中如何使用中间件?
这里以你示例中使用的Express框架为例,中间件分三类,使用逻辑统一都是引入后通过app.use()挂载,或者绑定到对应路由/控制器上即可:
- 内置中间件:比如你代码里的
express.json(),用来解析请求体的JSON数据,直接全局挂载后所有请求都会触发该逻辑 - 第三方中间件:比如示例中的
helmet(安全响应头处理)、morgan(请求日志打印),安装引入后直接通过app.use()挂载即可全局生效 - 自定义中间件:就是你写在
project/controllers/auth.js里的verifyToken鉴权类的自定义逻辑,导出后引入到入口文件,按需挂载即可使用
问题2:如何让中间件仅作用于部分特定请求?
有3种常用的实现方式,可直接适配你现有代码:
- 限定路由组生效:挂载路由时把中间件作为第二个参数传入,比如你要让所有
/api/user开头的接口都走鉴权,/api/auth的登录注册接口不走,直接调整app.js的路由挂载逻辑即可 - 限定单条路由生效:如果不需要整个路由组都触发中间件,只需要给特定接口加逻辑,就在路由定义时把中间件作为第二个参数传入,比如
router.get('/user/info', verifyToken, 你的控制器逻辑),同文件下其他没加中间件的路由不会生效 - 动态判断生效:如果路径匹配规则满足不了需求,直接在中间件内部加逻辑判断即可,比如你只想给POST请求加鉴权,就在中间件开头加
if(req.method !== 'POST') return next(),符合跳过条件的请求会直接进入后续逻辑
代码调整示例
app.js
const express = require("express"); const { User } = require("./models/user"); const morgan = require("morgan"); const dotenv = require("dotenv").config(); const helmet = require("helmet"); // 引入自定义鉴权中间件 const { verifyToken } = require("./controllers/auth") const app = express(); const userRoute = require("./routes/user"); const authRoute = require("./routes/auth"); // 全局生效的中间件 app.use(express.json()); app.use(helmet()); app.use(morgan("common")); // 仅/api/user开头的路由会触发鉴权中间件 app.use("/api/user", verifyToken, userRoute); // /api/auth下的接口不需要鉴权,直接挂载 app.use("/api/auth", authRoute); app.listen({ port: 7999 }, () => { console.log("服务启动成功"); });
project/controllers/auth.js
// 原代码漏了jsonwebtoken引入,这里补上 const jwt = require("jsonwebtoken") const verifyToken = async (req, res, next) => { const token = req.header("auth-token"); if (!token) return res.status(403).send("无访问权限"); try { const verified = jwt.verify(token, process.env.TOKEN_SECRET); req.user = verified; // 校验通过,进入后续逻辑 next(); } catch (error) { return res.status(500).json("TOKEN无效"); } }; // 导出中间件才能在其他文件引入使用 module.exports = { verifyToken }
内容的提问来源于stack exchange,提问作者n9p4
相关产品推荐
相关产品推荐

