JWT认证401无授权用户访问问题排查求助
问题描述
使用Thunder Client测试时,JWT令牌生成成功后/p3接口可正常访问,但访问/p4接口查询数据库验证用户身份时,始终返回401状态码及“未授权用户访问”错误,尝试多个用户凭证结果一致。
/p3接口代码
app.get('/p3', async (req, res) => { let token = req.headers.authorization console.log('Main token: ' + token) if (!token) { return res.status(401).json({ message: '未授权' }); } try { token = token.split(' ')[1]; const user = jwt.verify(token, 'secret-key'); console.log(user); } catch (e) { return res.status(400).json({ message: '无效令牌' }); } return res.status(200).json({ message: '这是私有路由' }); })
错误信息
{ "message": "Un-authorization user access" }
/p4接口信息
- 路由:
http://localhost:4000/p4 - 代码:
app.get('/p4', async (req, res) => { let token = req.headers.authorization console.log('Main token: ' + token) if (!token) { return res.status(401).json({ message: '未授权访问' }); } try { token = token.split(' ')[1]; const decoded = jwt.verify(token, 'secret-key'); const user = await User.findById(decoded._id); console.log(user); if (!user) { return res.status(401).json({ message: '未授权用户访问' }); } } catch (e) { return res.status(400).json({ message: '无效令牌' }); } return res.status(200).json({ message: '这是私有路由' }); })
登录接口代码
app.post('/login', async (req, res, next) => { console.log(req.body); const { email, password } = req.body try { const user = await User.findOne({ email }); console.log(user) if (!user) { return res.status(400).json({ message: "无效凭证,请先注册" }); } const isMatchPassword = await bcrypt.compare(password, user.password) if (!isMatchPassword) { return res.status(400).json({ message: "无效凭证,请先注册" }); } delete user._doc.password delete user._doc._id delete user._doc.roles const token = jwt.sign(user._doc, 'secret-key', { expiresIn: '1h' }) return res.status(200).json({ message: "登录成功", token }); } catch (e) { next(e); } });
问题原因与解决方法
核心问题出在登录接口的令牌生成逻辑:你删除了user._doc._id字段,导致JWT令牌的Payload里根本没有用户ID。而/p4接口尝试用decoded._id去数据库查询用户,自然找不到匹配数据,返回401错误。
修复步骤
- 修改登录接口代码,删除
delete user._doc._id这一行,确保用户ID被包含在JWT的Payload中:
delete user._doc.password // 移除这行代码:delete user._doc._id delete user._doc.roles
- 重新登录获取新的令牌,再测试
/p4接口即可正常访问。
额外验证建议
- 在
/p3接口中打印user对象,确认Payload里是否包含_id字段,验证令牌内容是否正确。 - 用JWT解码工具解析生成的令牌,检查Payload结构是否符合预期。
内容的提问来源于stack exchange,提问作者President Jam
相关产品推荐
相关产品推荐

