未登录时无法跳转至登录页?问题排查求助
问题分析与修复方案
核心问题拆解
后端代码问题
- 未处理Authorization头缺失/格式错误的情况
当用户未登录时,localStorage中无token,前端请求头的Authorization会是Bearer null,若完全没有该头,req.headers["authorization"]为undefined,直接调用split()会抛出错误,进入catch块返回500,而非预期的401/403。 - 错误捕获过于笼统
JWT验证失败(如token无效、过期)时,统一返回500服务器错误,未根据错误类型返回对应状态码(如401未授权),导致前端无法准确判断跳转时机。
前端代码问题
- 跳转逻辑位置错误
Axios仅在响应状态码为2xx时进入try块的response处理逻辑,后端返回的403/404/500都会触发catch块,因此if (response.status !== 201) { navigate("/login") }永远不会执行。 - 未在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
相关产品推荐
相关产品推荐

