未携带Auth Token无法登录的JWT认证问题排查
解决Node.js + React待办应用登录时「invalid token」问题
你的登录功能失效核心是前后端代码各存在一处逻辑错误,导致生成的Token格式异常或请求被提前拦截,以下是具体修正方案:
1. 后端验证逻辑颠倒错误
在登录接口的参数验证环节,代码错误地将「无验证错误」的情况判定为需要返回400错误,直接拦截了合法的登录请求,根本无法进入Token生成流程。
修正后后端代码
router.post("/login", fetchUser, [ body("email", "Enter a valid email").isEmail(), body("password", "Password cannot be blank").exists(), ], async (req, res) => { let success = false; // 修正逻辑:仅当存在验证错误时返回400 const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } try { const { email, password } = req.body; let user = await User.findOne({ email }); if (!user) { success = false; return res.status(400).json({ success, error: "Please enter the correct credentials" }); } const comparePassword = await bcrypt.compare(password, user.password); if (!comparePassword) { success = false; return res.status(400).json({ success, error: "Please enter the correct credentials" }); } const data = { user: { id: user.id, }, }; success = true; let authToken = jwt.sign(data, JWT_Secret); res.json({ success, authToken }); } catch (error) { res.status(500).send("Internal error occured"); } });
2. 前端Token存储格式错误
json.authToken本身就是标准的JWT字符串,你用JSON.stringify处理后会给Token套上额外的双引号,导致存入localStorage的Token格式完全无效。
修正后前端登录函数
const handleSubmit = async (e) => { e.preventDefault(); const response = await fetch('http://localhost:5000/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: credentials.email, password: credentials.password }) }); const json = await response.json(); if (json.success) { // 直接存储原始Token字符串,无需JSON序列化 localStorage.setItem('token', json.authToken); showAlert('Successfully Logged in'); navigate("/"); } else { alert("Invalid credentials"); } }
验证步骤
- 重启后端服务,确保修正后的代码生效
- 测试登录后,打开浏览器开发者工具的「Application」面板,检查localStorage中的
token值,应为不带引号的JWT字符串 - 后续接口请求携带该Token即可正常通过身份验证
内容的提问来源于stack exchange,提问作者Ashi Singh
相关产品推荐
相关产品推荐

