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

API中JWT Token验证失败问题求助及代码排查

JWT验证失败排查(返回"Invalid token or expired token")

我正在构建API并实现JWT Token功能,目前能正常生成Token,但验证时总是返回detail="Invalid token or expired token."错误。移除验证逻辑的判断后,任意字符串都被视为有效,因此确定问题出在验证相关代码里。

原代码片段

第一段:JWT核心逻辑

# Responsible for signing, encoding, decoding and returning JWTs
JWT_SECRET = config("secret")
JWT_ALGORITHM = config("algorithm")

# This returns the generated tokens
def token_response(token: str):
    return {
        "access token": token
    }

# This is used for signing the JWT string
def signJWT(userID: str) -> Dict[str, str]:
    payload = {
        "userID": userID,
        "expiry": time.time() + 600
    }
    token = jwt.encode(payload, JWT_SECRET, algorithm=JWT_ALGORITHM)
    return token_response(token)

def decodeJWT(token: str) -> dict:
    try:
        decode_token = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
        return decode_token if decode_token['expires'] >= time.time() else None
    except:
        return {}

第二段:Bearer验证类

class JWTBearer(HTTPBearer):
    def __init__(self, auto_error: bool = True):
        super(JWTBearer, self).__init__(auto_error=auto_error)

    async def __call__(self, request: Request):
        credentials: HTTPAuthorizationCredentials = await super(JWTBearer, self).__call__(request)
        if credentials:
            if not credentials.scheme == "Bearer":
                raise HTTPException(status_code=403, detail="Invalid authentication scheme.")
            if not self.verify_jwt(credentials.credentials):
                raise HTTPException(status_code=403, detail="Invalid token or expired token.")
            return credentials.credentials
        else:
            raise HTTPException(status_code=403, **detail="Invalid authorization code."**)

    def verify_jwt(self, jwtoken: str) -> bool:
        isTokenValid: bool = False

        try:
            payload = decodeJWT(jwtoken)
        except:
            payload = None
        if payload:
            isTokenValid = True
            
        return isTokenValid

问题分析与修复

核心问题点

  1. 键名不匹配:生成Token时payload用的是expiry,但解码时错误访问decode_token['expires'],直接触发KeyError进入except分支,返回空字典,导致验证失败。
  2. 过期时间处理不规范:JWT标准使用exp字段存储过期时间,且要求是整数时间戳;原代码自定义的expiry字段不符合规范,且jwt库本身会自动校验exp,无需手动判断。
  3. 语法错误:__call__方法中抛出HTTPException时,错误使用**detail="...",应为detail="..."。
  4. 冗余异常捕获:verify_jwt中的try块完全多余,decodeJWT已经处理了所有异常情况,反而会掩盖潜在问题。

修正后的代码

修正后的JWT核心逻辑

import time
from typing import Dict
import jwt
# 替换为你的实际配置导入路径
from your_config_module import config

JWT_SECRET = config("secret")
JWT_ALGORITHM = config("algorithm")

def token_response(token: str):
    return {
        "access token": token
    }

def signJWT(userID: str) -> Dict[str, str]:
    # 使用JWT标准exp字段,存储整数时间戳
    payload = {
        "userID": userID,
        "exp": int(time.time() + 600)
    }
    token = jwt.encode(payload, JWT_SECRET, algorithm=JWT_ALGORITHM)
    return token_response(token)

def decodeJWT(token: str) -> dict:
    try:
        # jwt.decode自动校验exp,无需手动判断
        return jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
    except jwt.ExpiredSignatureError:
        return None  # 明确标记过期情况
    except jwt.InvalidTokenError:
        return {}  # 其他无效token情况

修正后的Bearer验证类

from fastapi import HTTPException, Request
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials

class JWTBearer(HTTPBearer):
    def __init__(self, auto_error: bool = True):
        super(JWTBearer, self).__init__(auto_error=auto_error)

    async def __call__(self, request: Request):
        credentials: HTTPAuthorizationCredentials = await super(JWTBearer, self).__call__(request)
        if credentials:
            if not credentials.scheme == "Bearer":
                raise HTTPException(status_code=403, detail="Invalid authentication scheme.")
            if not self.verify_jwt(credentials.credentials):
                raise HTTPException(status_code=403, detail="Invalid token or expired token.")
            return credentials.credentials
        else:
            # 修正语法错误
            raise HTTPException(status_code=403, detail="Invalid authorization code.")

    def verify_jwt(self, jwtoken: str) -> bool:
        payload = decodeJWT(jwtoken)
        # 只要payload非空且非None,即为有效
        return bool(payload)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 22:16:30