You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js+Express中如何区分带/不带中间件的路由并实现登录渲染

问题分析与解决方案

1. 重复根路由的核心问题

你定义了两个完全相同的GET /路由,Express会按照路由定义的顺序进行匹配,第一个无中间件的路由会被优先命中,带checklogin的路由永远不会被执行。必须合并为一个路由,通过中间件判断用户登录状态,在同一个路由逻辑中处理两种场景。

修改home/home.js的路由:

router.get('/', checklogin, (req,res)=>{
  // 登录状态下req会携带用户信息,未登录则无对应字段
  res.render('home/index',{
    email: req.email,
    name: req.username,
    role: req.role
  })
})

2. 修复checklogin中间件的逻辑错误

你的中间件在catch块中调用了两次next(),且错误处理逻辑混乱。正确的逻辑应该是:

  • 验证token成功:将用户信息挂载到req对象,调用next()继续执行路由
  • 验证失败/无token:不挂载用户信息,直接调用next()让路由自行处理未登录状态

修改后的中间件代码:

const checklogin = (req, res, next) => {
  const token = req.cookies.ntoken;
  try {
    if (token) { // 先判断是否存在token
      const decoded = jwt.verify(token, process.env.JWT_SECRET);
      const {username, email, role} = decoded;
      req.username = username;
      req.email = email;
      req.role = role;
    }
    next(); // 无论是否有有效token,都继续执行后续逻辑
  } catch (err) {
    console.log(err);
    // token无效时,不挂载用户信息,直接放行
    next();
  }
}

module.exports = checklogin;

3. Handlebars模板适配登录状态

在home/index.hbs中需要判断用户信息是否存在,再决定展示内容:

{{#if name}}
  <p>欢迎回来,{{name}}!</p>
  {{#if role '===' 'admin'}}
    <a href="/admin/dashboard">进入管理员面板</a>
  {{else if role '===' 'user'}}
    <a href="/user/dashboard">进入用户面板</a>
  {{/if}}
{{else}}
  <p>请<a href="/login">登录</a>后访问更多功能</p>
{{/if}}

4. 修复user路由的拼写错误

user.js中的路由存在拼写错误,checlogin改为checklogin:

router.get("/dashboard", checklogin, async (req, res) => {
  // 你的业务逻辑
})

5. 额外优化:拦截未登录用户访问dashboard

可以在checklogin中间件中添加逻辑,禁止未登录用户直接访问dashboard路由:

const checklogin = (req, res, next) => {
  const token = req.cookies.ntoken;
  try {
    if (token) {
      const decoded = jwt.verify(token, process.env.JWT_SECRET);
      const {username, email, role} = decoded;
      req.username = username;
      req.email = email;
      req.role = role;
    }
    // 访问dashboard且未登录时,重定向到登录页
    if ((req.path.includes('/dashboard')) && !req.username) {
      return res.redirect('/login');
    }
    next();
  } catch (err) {
    console.log(err);
    if (req.path.includes('/dashboard')) {
      return res.redirect('/login');
    }
    next();
  }
}

完成以上调整后,用户登录后重定向到/就能正确展示用户名,不同角色的用户也能访问对应的dashboard路由。

内容的提问来源于stack exchange,提问作者Shabnam Sabah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:07:10