Skip to main content

ChewyAuthSDK

生产可用的 Python 统一认证 SDK

统一 Keycloak JWT 校验逻辑,同时支持 Django 和 FastAPI。

Python Version License


🎯 核心特性

  • 统一 Keycloak JWT 校验 - 基于 RS256 + JWKS
  • 同时支持 Django 和 FastAPI - 一套 SDK 适配两大框架
  • 独立校验 - 无需 Gateway,无需 introspection API
  • 高性能 - 本地 JWT 解析 + JWKS 缓存
  • 完整透传 Claims - 保留 Keycloak 原始用户信息
  • 开箱即用 - 一行配置即可启用

📦 安装

# 基础安装(仅 JWT 校验)
pip install chewy-auth-sdk

# Django 项目
pip install chewy-auth-sdk[django]

# FastAPI 项目
pip install chewy-auth-sdk[fastapi]

# 同时支持 Django 和 FastAPI
pip install chewy-auth-sdk[all]

🚀 快速开始

1. 配置 SDK

在项目启动时配置一次即可:

from chewy_auth_sdk import configure

configure(
    KEYCLOAK_ISSUER="https://keycloak.example.com/realms/your-realm",
    KEYCLOAK_AUDIENCE="account",  # 可选
    CACHE_TTL=300,  # JWKS 缓存时间(秒)
)

2. Django 集成

2.1 添加 Middleware

settings.py 中添加:

MIDDLEWARE += [
    "chewy_auth_sdk.middleware.django.ChewyAuthMiddleware",
]

2.2 在视图中使用

from django.http import JsonResponse

def my_view(request):
    # request.user 是 AuthUser 对象或 None
    if request.user is None:
        return JsonResponse({"error": "Not authenticated"}, status=401)
    
    return JsonResponse({
        "username": request.user.username,
        "email": request.user.email,
        "roles": request.user.roles,
    })

2.3 使用装饰器进行权限控制

from chewy_auth_sdk.adapters.django import require_auth, require_role

@require_auth
def protected_view(request):
    return JsonResponse({"message": "Authenticated user only"})

@require_role("admin")
def admin_view(request):
    return JsonResponse({"message": "Admin only"})

3. FastAPI 集成

3.1 添加 Middleware

from fastapi import FastAPI
from chewy_auth_sdk.middleware.fastapi import ChewyAuthMiddleware

app = FastAPI()
app.add_middleware(ChewyAuthMiddleware)

3.2 在路由中使用

from fastapi import Request, Depends, HTTPException
from chewy_auth_sdk.adapters.fastapi import get_current_user, require_auth
from chewy_auth_sdk import AuthUser

@app.get("/profile")
def get_profile(request: Request):
    # request.state.user 是 AuthUser 对象或 None
    user = request.state.user
    if user is None:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    return {
        "username": user.username,
        "email": user.email,
        "roles": user.roles,
    }

# 使用 Dependency
@app.get("/me")
def get_me(user: AuthUser = Depends(require_auth)):
    return {"username": user.username}

3.3 使用 Dependency 进行权限控制

from chewy_auth_sdk.adapters.fastapi import require_role, require_any_role

@app.get("/admin")
def admin_endpoint(user: AuthUser = Depends(require_role("admin"))):
    return {"message": "Admin only"}

@app.get("/moderation")
def moderation_endpoint(
    user: AuthUser = Depends(require_any_role("admin", "moderator"))
):
    return {"message": "Admin or moderator"}

📚 核心概念

AuthUser 对象

所有认证成功的请求都会得到一个 AuthUser 对象:

class AuthUser:
    raw_claims: dict        # Keycloak 原始 claims(完整透传)
    sub: str                # 用户唯一标识
    username: str           # 用户名
    email: str | None       # 邮箱
    roles: list[str]        # 角色列表
    
    # 便捷方法
    def has_role(self, role: str) -> bool
    def has_any_role(self, *roles: str) -> bool
    def has_all_roles(self, *roles: str) -> bool

Token 校验流程

  1. 提取 Token - 从 Authorization: Bearer <token> header 中提取
  2. 获取公钥 - 从 Keycloak JWKS endpoint 获取(带缓存)
  3. 校验签名 - 使用 RS256 算法校验
  4. 校验 Claims - 验证 expissaud
  5. 构造用户对象 - 提取用户信息和角色

为什么不使用 Introspection?

不推荐 Introspection 的原因:

  • 每次请求都需要调用 Keycloak API(性能差)
  • 增加 Keycloak 服务器负载
  • 增加网络延迟
  • 单点故障风险

推荐使用 JWT + JWKS:

  • 本地校验,性能高
  • JWKS 缓存,减少网络请求
  • 无需依赖 Keycloak 可用性
  • 符合 OAuth2 / OIDC 标准最佳实践

⚙️ 高级配置

完整配置选项

from chewy_auth_sdk import configure

configure(
    # Keycloak 配置(必填)
    KEYCLOAK_ISSUER="https://keycloak.example.com/realms/your-realm",
    
    # Audience 校验(可选)
    KEYCLOAK_AUDIENCE="account",  # 如果不提供,不校验 audience
    VERIFY_AUDIENCE=True,  # 是否校验 audience
    
    # JWKS 配置(可选,自动推导)
    KEYCLOAK_JWKS_URI=None,  # 默认:{ISSUER}/protocol/openid-connect/certs
    CACHE_TTL=300,  # JWKS 缓存时间(秒)
    
    # Token 校验(可选)
    VERIFY_EXPIRATION=True,  # 是否校验 token 过期时间
    
    # 角色提取(可选)
    ROLES_CLAIM_PATH="realm_access.roles",  # 角色在 JWT 中的路径
    
    # Header 透传(可选,不推荐)
    ENABLE_HEADER_PASSTHROUGH=False,  # 是否启用 Gateway header 透传
    HEADER_USER_SUB="X-User-Sub",
    HEADER_USER_NAME="X-User-Name",
    HEADER_USER_ROLES="X-User-Roles",
)

Header 透传模式(可选)

如果你使用 Gateway 并希望透传用户信息,可以使用:

# Django
MIDDLEWARE += [
    "chewy_auth_sdk.middleware.django.ChewyAuthMiddlewareWithHeaderPassthrough",
]

# FastAPI
from chewy_auth_sdk.middleware.fastapi import ChewyAuthMiddlewareWithHeaderPassthrough
app.add_middleware(ChewyAuthMiddlewareWithHeaderPassthrough)

自定义角色路径

如果你的角色不在 realm_access.roles,可以自定义:

configure(
    KEYCLOAK_ISSUER="...",
    ROLES_CLAIM_PATH="resource_access.my-client.roles",  # 自定义路径
)

🧪 测试

# 安装开发依赖
pip install -e ".[dev]"

# 运行测试
pytest

📖 架构说明

项目结构

ChewyAuthSDK/
├── chewy_auth_sdk/
│   ├── __init__.py          # 公共 API
│   ├── settings.py          # 全局配置管理
│   ├── exceptions.py        # 统一异常定义
│   ├── jwks.py              # JWKS 管理和缓存
│   ├── token.py             # JWT 校验和 AuthUser
│   ├── context.py           # 请求上下文(可选)
│   ├── middleware/
│   │   ├── django.py        # Django Middleware
│   │   └── fastapi.py       # FastAPI Middleware
│   └── adapters/
│       ├── django.py        # Django 装饰器和工具
│       └── fastapi.py       # FastAPI Dependency 和工具
├── pyproject.toml
└── README.md

设计原则

  1. 职责分离 - 每个模块只做一件事
  2. 框架无关 - 核心逻辑不依赖 Django/FastAPI
  3. 易于扩展 - 可轻松支持新框架
  4. 生产就绪 - 异常处理、缓存、性能优化

🚫 明确禁止

ChewyAuthSDK 只做 Token 校验不实现以下功能:

  • ❌ 登录 / 跳转到 Keycloak
  • ❌ Refresh Token 处理
  • ❌ 用户信息存储(数据库)
  • ❌ Keycloak Admin API 调用
  • ❌ 强制依赖 Gateway

如需这些功能,请直接使用 Keycloak 官方库或其他专用工具。


🤝 贡献

欢迎提交 Issue 和 Pull Request!


📄 License

MIT License


🔗 相关链接


❓ FAQ

Q: 为什么不使用 Keycloak Python Adapter?

A: Keycloak 官方 Python Adapter 主要面向 OIDC 登录流程,对于纯 API 认证(微服务)场景过于复杂。ChewyAuthSDK 专注于 JWT 校验,更轻量、更灵活。

Q: 可以在生产环境使用吗?

A: 是的,ChewyAuthSDK 设计目标就是生产可用。包含完整的异常处理、缓存机制、性能优化。

Q: 如何处理 Token 过期?

A: Token 过期会抛出 TokenExpiredError,Middleware 会返回 401。客户端应该刷新 Token 后重试。

Q: 支持多个 Realm 吗?

A: 当前版本只支持单个 Realm。如需多 Realm,建议为每个服务独立配置 SDK。

Q: 性能如何?

A: JWT 本地校验 + JWKS 缓存,单次请求耗时 < 1ms。JWKS 缓存默认 5 分钟,可自定义。


Enjoy coding with ChewyAuthSDK! 🎉

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chewy_auth_sdk-0.1.0.tar.gz (26.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

chewy_auth_sdk-0.1.0-py3-none-any.whl (20.2 kB view details)

Uploaded Python 3

File details

Details for the file chewy_auth_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: chewy_auth_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 26.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.5

File hashes

Hashes for chewy_auth_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d90cf838b7c63baddc55f7b0dbb6e83fe40fa88892c8967d8a25b6cc6235830a
MD5 0c9f603d2e8ca04adcba6d34fc64a979
BLAKE2b-256 9f6b36747dc48f39e4928d47ca36e7bf5909d53638904db7aec99a9fb988d585

See more details on using hashes here.

File details

Details for the file chewy_auth_sdk-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for chewy_auth_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 390b293b8bba048c8533d43012d5efcc767c9925d8cebcd7251c6472133b7f82
MD5 f62ea377aa521a6f78f80645c8e9afa2
BLAKE2b-256 e034fbc5e99a972d4693bce3721c361dfe2e29ccc361532e5d69a4c0e2f8fd09

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page