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

如何用Python验证Laravel Passport生成的访问令牌?

验证Laravel Passport令牌(Python端共享数据库场景)

因为你的Python项目和Laravel共享数据库,不需要向Laravel发起验证请求,可根据Passport令牌的类型选择两种方案:

方案1:验证JWT格式令牌(密码授权模式)

如果你的令牌是Laravel Passport密码授权生成的JWT格式,直接用Python的JWT库解析验证即可:

  1. 从Laravel项目中获取公钥(路径为storage/oauth-public.key)
  2. 安装依赖库:
pip install pyjwt cryptography
  1. 验证代码示例:
import jwt
from jwt.exceptions import InvalidTokenError
from datetime import datetime

def validate_jwt_token(token):
    # 加载Laravel Passport公钥
    with open("/path/to/oauth-public.key", "r") as f:
        public_key = f.read()
    
    try:
        # 解析并验证令牌,RS256是Passport默认的加密算法
        payload = jwt.decode(
            token,
            public_key,
            algorithms=["RS256"],
            options={"verify_aud": False}  # 根据你的Passport配置决定是否验证aud字段
        )
        # 额外检查令牌是否过期(pyjwt默认会自动验证exp)
        if datetime.utcfromtimestamp(payload["exp"]) < datetime.utcnow():
            return False, "Token expired"
        return True, payload
    except InvalidTokenError as e:
        return False, str(e)

方案2:验证个人访问令牌(随机字符串格式)

如果是Passport默认的个人访问令牌(非JWT的随机字符串),直接查询共享数据库的oauth_access_tokens表验证:

  1. 安装数据库依赖(以MySQL为例):
pip install pymysql
  1. 验证代码示例:
import pymysql
from datetime import datetime

def validate_personal_token(token, db_config):
    conn = pymysql.connect(**db_config)
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    # 查询令牌是否存在、未撤销、未过期
    query = """
        SELECT id FROM oauth_access_tokens 
        WHERE id = %s AND revoked = 0 AND expires_at > %s
    """
    cursor.execute(query, (token, datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")))
    result = cursor.fetchone()
    
    cursor.close()
    conn.close()
    
    return result is not None

# 调用示例
db_config = {
    "host": "你的数据库地址",
    "user": "数据库用户名",
    "password": "数据库密码",
    "db": "共享数据库名"
}
is_valid = validate_personal_token("你的令牌字符串", db_config)

实现Python项目的验证中间件(以FastAPI为例)

把验证逻辑封装成中间件/依赖,方便在路由中复用:

from fastapi import Depends, HTTPException, Request

async def auth_middleware(request: Request):
    auth_header = request.headers.get("Authorization")
    if not auth_header or not auth_header.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="无效的授权头")
    
    token = auth_header.split(" ")[1]
    # 根据你的令牌类型选择验证函数
    is_valid, payload = validate_jwt_token(token)
    # 或者 is_valid = validate_personal_token(token, db_config)
    
    if not is_valid:
        raise HTTPException(status_code=401, detail="令牌无效或已过期")
    return payload

# 受保护的路由示例
@app.get("/api/protected")
async def protected_route(user_info=Depends(auth_middleware)):
    return {"message": "已通过验证", "user_id": user_info["sub"]}

注意事项

  • 确保Python项目有读取oauth_access_tokens表的数据库权限
  • 使用JWT验证时,要同步Laravel的公钥,避免公钥更新后验证失败
  • 处理时间时统一用UTC时间,避免时区差异导致过期判断错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:45:56