Node.js环境下实现点击导航栏链接时的用户JWT身份验证问题
失效原因排查
首先确认以下几个常见问题:
- 路由执行顺序错误:如果你的
express.static静态资源中间件注册位置早于自定义的页面路由,静态HTML请求会被express.static直接响应,完全不会触发你写的鉴权路由逻辑 - 中间件命名不匹配:你定义的鉴权中间件名为
Authenticate,但路由中引入的是auth,如果没有做别名赋值,会因为找不到对应中间件导致逻辑不生效 - 静态文件优先匹配:只要静态目录下存在对应路径的HTML文件,
express.static默认会优先返回,跳过后续自定义路由
修复方案
1. 调整中间件注册顺序
把所有需要鉴权的自定义路由放在express.static注册之前,鉴权通过后再返回对应页面:
// 先注册需要鉴权的路由 app.get("/mycourses.html", Authenticate, (req, res) => { console.log(req.email); // 鉴权通过后返回对应静态页面 res.sendFile(path.join(__dirname, "你的静态资源目录路径", "mycourses.html")) }) // 最后注册静态资源中间件 app.use(express.static(path.join(__dirname, "你的静态资源目录路径")))
2. 修改鉴权中间件的响应逻辑
当前中间件校验失败时返回的是JSON格式,普通页面跳转场景下用户只能看到 raw 字符串,改为未登录时重定向到登录页即可:
const Authenticate = async (req, res, next) => { try { const token = req.cookies.jwtoken; // 提前判断token不存在的场景,减少无效逻辑 if (!token) throw new Error("未登录,请先登录"); const verifyToken = jwt.verify(token, JWT_SECRET); const mainUser = await User.findOne({ _id: verifyToken._id, "tokens.token": token, }); if (!mainUser) { throw new Error("用户不存在"); } req.token = token; req.mainUser = mainUser; req.email = mainUser.email; req.userID = mainUser._id; next(); } catch (error) { console.log(error); // 未通过鉴权时重定向到登录页,可携带当前页面地址,登录后跳回 res.redirect(`/login.html?redirect=${encodeURIComponent(req.originalUrl)}`); // 如果需要弹窗提示,可以用以下写法 // res.send(`<script>alert('${error.message}');location.href='/login.html'</script>`) } };
3. 批量配置导航栏鉴权
不需要逐个给每个导航链接写路由,可以用正则批量匹配所有需要鉴权的页面,比如排除首页、登录页、注册页之外的所有HTML页面都加鉴权:
// 正则含义:匹配所有不是以/index、/login、/register开头的HTML页面请求 app.get(/^\/(?!index|login|register).*\.html$/, Authenticate, (req, res, next) => { // 鉴权通过后交给静态资源中间件处理 next() })
内容的提问来源于stack exchange,提问作者Rohan Sai Buddhi
相关产品推荐
相关产品推荐

