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

未登录时无法跳转至登录页?问题排查求助

问题分析与修复方案

核心问题拆解

后端代码问题

  1. 未处理Authorization头缺失/格式错误的情况
    当用户未登录时,localStorage中无token,前端请求头的Authorization会是Bearer null,若完全没有该头,req.headers["authorization"]为undefined,直接调用split()会抛出错误,进入catch块返回500,而非预期的401/403。
  2. 错误捕获过于笼统
    JWT验证失败(如token无效、过期)时,统一返回500服务器错误,未根据错误类型返回对应状态码(如401未授权),导致前端无法准确判断跳转时机。

前端代码问题

  1. 跳转逻辑位置错误
    Axios仅在响应状态码为2xx时进入try块的response处理逻辑,后端返回的403/404/500都会触发catch块,因此if (response.status !== 201) { navigate("/login") }永远不会执行。
  2. 未在catch块中处理跳转
    catch块仅打印错误,未针对未授权类错误执行跳转逻辑,导致未登录时前端无反应。

修正后的代码

后端验证Token代码

const verifyToken = async (req, res, next) => {
  try {
    // 先检查Authorization头是否存在且格式正确
    const authHeader = req.headers["authorization"];
    if (!authHeader || !authHeader.startsWith("Bearer ")) {
      return res.status(401).json({ message: "未提供有效令牌" });
    }
    const token = authHeader.split(" ")[1];
    if (!token) {
      return res.status(401).json({ message: "令牌为空" });
    }
    const decodedPayload = jwt.verify(token, process.env.JWT_KEY);
    req.username = decodedPayload.username;
    next();
  } catch (err) {
    // 区分JWT错误类型,返回对应状态码
    if (err.name === "JsonWebTokenError") {
      return res.status(401).json({ message: "无效令牌" });
    } else if (err.name === "TokenExpiredError") {
      return res.status(401).json({ message: "令牌已过期" });
    } else {
      return res.status(500).json({ message: "服务器错误" });
    }
  }
};

router.get("/home", verifyToken, async (req, res) => {
  try {
    console.log(req.username);
    if (req.username !== "admin") {
      return res.status(403).json({ message: "无访问权限" });
    }
    return res.status(200).json({ message: "用户已登录" });
  } catch (err) {
    return res.status(500).json({ message: "服务器错误" });
  }
});

前端跳转逻辑代码

const fetchUser = async () => {
  try {
    const token = localStorage.getItem("token");
    // 本地无token直接跳转,避免无效请求
    if (!token) {
      navigate("/login");
      return;
    }
    const response = await axios.get("http://localhost:3001/auth/home", {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    });
    // 登录成功后的逻辑(如存储用户信息)
  } catch (err) {
    console.log(err);
    // 捕获未授权类状态码,跳转登录页并清除无效token
    if (err.response?.status === 401 || err.response?.status === 403) {
      localStorage.removeItem("token");
      navigate("/login");
    }
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 05:22:40