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

使用JQuery携带请求头访问Node.js受保护路由问题

解决JWT Token在受保护路由跳转时的携带问题

你遇到的核心问题是:直接用window.location.pathname跳转时,浏览器发起的GET请求不会自动携带存在sessionStorage里的Token到请求头,导致服务器的verifyToken中间件无法验证身份,返回403错误。咱们一步步来解决这个问题:

1. 先修正sessionStorage的存储错误

你当前的代码里:

sessionStorage.setItem(token, token);

这里把Token的值同时作为键名和值存储了,后续很难正确取出Token。应该用一个固定的键名,比如authToken:

const token = response.token;
sessionStorage.setItem('authToken', token); // 固定键名存储,方便后续取出

2. 选择合适的方式携带Token跳转受保护路由

根据你的应用场景,有两种常用方案:

方案一:用AJAX请求受保护路由并手动携带Token(推荐,适合前后端分离场景)

直接跳转的浏览器请求不会自动带Token,所以我们改用AJAX发起GET请求,手动在请求头里加入Token,然后渲染返回的页面内容:

// 登录成功后替换原来的window.location跳转代码
const token = response.token;
sessionStorage.setItem('authToken', token);

$.ajax({
  url: '/LimeLINE/chatroom',
  type: 'GET',
  // 在请求头里加入Authorization,格式为「Bearer + 空格 + Token」
  headers: {
    'Authorization': `Bearer ${token}`
  },
  success: function(htmlContent) {
    // 替换当前页面内容为服务器返回的chatroom页面
    document.body.innerHTML = htmlContent;
    // 更新浏览器URL,让地址栏显示正确的路由(可选,优化用户体验)
    window.history.pushState({}, '', '/LimeLINE/chatroom');
  },
  error: function(xhr) {
    if (xhr.status === 403) {
      alert('身份验证失败,请重新登录');
      window.location.pathname = '/'; // 跳回登录页
    } else {
      alert('页面加载失败,请稍后重试');
    }
  }
});

方案二:将Token存在Cookie中,让浏览器自动携带

Cookie会在每次请求时自动发送给服务器,所以如果把Token存在Cookie里,直接跳转也能带上身份信息:

// 登录成功后存储Token到Cookie
const token = response.token;
// 可根据需求设置过期时间、secure(仅HTTPS下生效)、SameSite等参数
document.cookie = `authToken=${token}; path=/; SameSite=Strict`;

// 然后直接跳转
window.location.pathname = '/LimeLINE/chatroom';

对应的,你需要修改verifyToken中间件,从Cookie中读取Token:

function verifyToken(req, res, next) {
  // 从Cookie中获取Token
  const token = req.cookies.authToken;
  
  if (!token) {
    return res.status(403).json({ message: "No token found" });
  }
  
  req.token = token;
  next();
}

注意:如果用Cookie存储,建议开启HttpOnly和Secure属性防止XSS攻击,比如:

document.cookie = `authToken=${token}; path=/; HttpOnly; Secure; SameSite=Strict`;

不过HttpOnly的Cookie无法通过前端JS读取,后续如果需要前端用Token发起其他请求,就得从服务器端处理。

3. 修正服务器端的JWT生成代码

你的登录接口里有个小错误:res.statusCode(500)是无效的,应该用res.status(500)来设置状态码:

app.post('/login-user', (req, res) => {
  user.loginUser(req.body, (err, jResult) => {
    if (err) {
      return res.send(jResult);
    }
    jwt.sign({ user: jResult }, "supersecret", (err, token) => {
      if (err) {
        return res.status(500).json({ message: "生成Token失败" }); // 修正此处的状态码设置
      }
      console.log(token);
      return res.json({ token: token });
    });
  });
});

4. 确认verifyToken中间件的实现(方案一对应)

如果用方案一的Authorization头方式,你的verifyToken中间件应该从请求头里解析Token:

function verifyToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  // 提取Bearer后面的Token部分
  const token = authHeader && authHeader.split(' ')[1];
  
  if (!token) {
    return res.status(403).json({ message: "No token found" });
  }
  
  req.token = token;
  next();
}

这样调整后,就能正确携带Token访问受保护路由了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:09:35