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

Node.js中Try/Catch未捕获JWT解构错误问题求助

问题排查:患者认证中间件解构报错而非预期未授权提示

问题场景

使用以下患者认证中间件保护/patient路由时,医生用户访问该路由抛出"msg": "Cannot destructure property 'name' of '(intermediate value)' as it is null."错误,而非预期的未授权提示,且代码此前运行正常。

患者认证中间件代码

interface MyUserRequest extends Request {
    user?: any;
}

type MyToken = {
    patientId: number
    name: string
}

const SECRET: Secret = process.env.PATIENT_SECRET!

const patientAuthMiddleware = async (req: MyUserRequest, res: Response, next:NextFunction) => {
    const {token} = req.cookies

    try{
        const {patientId, name} = jwt.verify(token, SECRET) as MyToken
        req.user = {patientId, name}  
        next()
    }
    catch(error){
        throw new UnauthenticatedError('You are not authorized to access this route')
    }
}

路由配置代码

app.use('/patient', patientAuthMiddleware, patientRouter)

排查分析

  • 直接触发原因:jwt.verify(token, SECRET)返回了null,导致解构name时触发类型错误,且这个返回null的情况未被try/catch捕获(部分JWT库在特定验证失败场景下不会抛出异常,而是返回null)。
  • 深层诱因:
    1. 医生用户的Cookie中存在名为token的Cookie,但该token是用医生角色的密钥签发的,而非患者的PATIENT_SECRET。此时用患者密钥验证医生token,JWT库未抛出签名错误,反而返回null。
    2. 此前代码正常是因为医生用户Cookie中无此冲突token,近期医生用户登录后Cookie中新增了这个同名token,导致冲突。

解决办法

1. 增加前置校验与解码结果验证

在调用jwt.verify前检查token是否存在,解码后验证结果有效性,确保异常能被正确捕获:

const patientAuthMiddleware = async (req: MyUserRequest, res: Response, next:NextFunction) => {
    const {token} = req.cookies

    // 先检查token是否存在
    if (!token) {
        throw new UnauthenticatedError('You are not authorized to access this route')
    }

    try{
        const decoded = jwt.verify(token, SECRET) as MyToken
        // 验证解码结果是否包含必要字段
        if (!decoded || typeof decoded.patientId !== 'number' || !decoded.name) {
            throw new Error('Invalid token payload')
        }
        req.user = {patientId: decoded.patientId, name: decoded.name}  
        next()
    }
    catch(error){
        throw new UnauthenticatedError('You are not authorized to access this route')
    }
}

2. 区分不同角色的Cookie键名

将患者token的Cookie名改为patient_token,医生token改为doctor_token,彻底避免同名Cookie冲突:

  • 中间件中修改为const {patient_token: token} = req.cookies
  • 签发患者token时,设置Cookie的key为patient_token

3. 校验JWT库版本与异常逻辑

确认使用的JWT库(如jsonwebtoken)版本,部分旧版本可能存在验证失败返回null而非抛出异常的问题,建议升级到稳定版本,并检查全局异常处理中间件是否拦截了jwt.verify的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:41:00