如何在ReactJS中使用JWT验证用户是否已登录
JWT登录验证问题修复方案
前端代码修正
你当前的axios请求错误地将请求头放在了请求体中,导致后端无法正确获取token。正确做法是将headers作为axios请求的第三个配置参数传入:
const ApproveRequest = (approveOption) => { if (approveOption === "approve") { let request = 1; const accessToken = cookies.getItem("accessToken"); axios.put( "http://localhost:3001/cash/approverequest", { approved: request, id: id }, { headers: { accessToken: accessToken }, withCredentials: true } ).then((response) => { if(response.data.error) { console.log(response.data.error); } else { setCashObject({ ...cashObject, request: request }); alert("Request Approved"); } }).catch(err => { console.error("请求失败:", err); alert("Failed to update the request, please contact the dev"); }); } else { alert("Failed to update the request, please contact the dev"); } }
后端JWT验证中间件修正
你的中间件存在三个核心问题,修复后才能正确完成登录验证:
- 从
req.header获取token不符合Cookie存储方案,应直接从req.cookies读取(需先安装cookie-parser中间件) return next需改为调用next()才能进入后续路由处理- 验证通过后应挂载用户信息到
req对象,方便后续业务逻辑使用
const jwt = require('jsonwebtoken'); const verify = jwt.verify; // 先执行安装:npm install cookie-parser // 在项目入口文件(如app.js)中启用: // const cookieParser = require('cookie-parser'); // app.use(cookieParser()); const validateToken = (req, res, next) => { const accessToken = req.cookies.accessToken; if(!accessToken) { return res.status(401).json({error: "User not authenticated"}); } try{ const validToken = verify(accessToken, "bluedragon14S"); req.user = validToken; req.authenticated = true; next(); } catch (err) { return res.status(403).json({error: "Invalid or expired token"}); } } module.exports = { validateToken };
后端路由优化
完善路由的错误处理逻辑,确保验证通过后才能执行更新操作:
router.put("/approverequest", validateToken, async (req, res) => { try { const { request = 1, id } = req.body; if (!id) { return res.status(400).json({error: "Request ID is required"}); } const result = await Cash.update( {request: request}, {where: {id: id} } ); if (result[0] === 0) { return res.status(404).json({error: "Request not found"}); } res.json({success: true, request: request}); } catch (err) { console.error("更新失败:", err); res.status(500).json({error: "Internal server error"}); } });
额外登录状态检查建议
- 前端全局拦截:封装axios实例,自动携带token并统一处理未授权错误
const api = axios.create({ baseURL: "http://localhost:3001", withCredentials: true }); api.interceptors.request.use(config => { const accessToken = cookies.getItem("accessToken"); if (accessToken) { config.headers.accessToken = accessToken; } return config; }, err => Promise.reject(err)); api.interceptors.response.use(response => response, err => { if (err.response?.status === 401 || err.response?.status === 403) { window.location.href = "/login"; } return Promise.reject(err); });
- 组件内预检查:在组件挂载时验证token有效性,避免未授权用户进入页面
useEffect(() => { const checkAuth = async () => { const accessToken = cookies.getItem("accessToken"); if (!accessToken) { window.location.href = "/login"; return; } try { const response = await api.get("/auth/verify"); if (!response.data.authenticated) { window.location.href = "/login"; } } catch (err) { window.location.href = "/login"; } }; checkAuth(); }, []);
内容的提问来源于stack exchange,提问作者Ramel Jay Cuña
相关产品推荐
相关产品推荐

