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

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错误。

修复步骤

  1. 修改登录接口代码,删除delete user._doc._id这一行,确保用户ID被包含在JWT的Payload中:
delete user._doc.password
// 移除这行代码:delete user._doc._id
delete user._doc.roles
  1. 重新登录获取新的令牌,再测试/p4接口即可正常访问。

额外验证建议

  • 在/p3接口中打印user对象,确认Payload里是否包含_id字段,验证令牌内容是否正确。
  • 用JWT解码工具解析生成的令牌,检查Payload结构是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 18:27:24