mdfarhankc/fastapi-fullauth

GitHub: mdfarhankc/fastapi-fullauth

为 FastAPI 提供生产级、原生异步的身份验证与授权库,覆盖完整的安全管控与可扩展能力。

Stars: 1 | Forks: 0

FastAPI FullAuth

FastAPI FullAuth

适用于 FastAPI 的生产级、原生异步的身份验证与授权。

PyPI Python CI License Docs

文档: https://mdfarhankc.github.io/fastapi-fullauth
源代码: https://github.com/mdfarhankc/fastapi-fullauth

为你的 **FastAPI** 项目添加完整的身份验证与授权系统。FastAPI FullAuth 旨在开箱即用、原生异步、可插拔——内置 JWT 令牌、刷新轮换、密码哈希、邮箱验证、OAuth2 社交登录以及基于角色的访问控制。 ## 功能特性 - **JWT 访问令牌 + 刷新令牌**,支持可配置的过期时间 - **刷新令牌轮换** 并检测重复使用——重放时吊销整个会话族 - **密码哈希** 使用 Argon2id(默认)或 bcrypt,支持透明重哈希 - **邮箱验证** 与 **密码重置** 流程,支持事件钩子 - **OAuth2 社交登录** — Google 与 GitHub,支持多重定向 URI - **基于角色的访问控制** — `CurrentUser`、`VerifiedUser`、`SuperUser`、`require_role()` - **速率限制** — 每路由认证限制 + 全局中间件(内存或 Redis) - **CSRF 保护** 与 **安全头** 中间件,自动装配 - **可插拔适配器** — SQLModel 或 SQLAlchemy - **泛型类型参数** — 可自定义模式并获得完整的 IDE 支持与类型安全 - **可组合的路由器** — 仅包含你需要的路由组 - **事件钩子** — `after_register`、`after_login`、`send_verification_email` 等 - **自定义 JWT 声明** — 在令牌中嵌入应用特定数据 - **结构化日志** — 所有认证事件、安全违规与失败均被记录 - **Redis 支持** — 令牌黑名单与速率限制后端 - **支持 Python 3.10 – 3.14** ## 安装 ``` pip install fastapi-fullauth # 使用 ORM 适配器 pip install fastapi-fullauth[sqlmodel] pip install fastapi-fullauth[sqlalchemy] # 使用 Redis 进行令牌黑名单管理 pip install fastapi-fullauth[sqlmodel,redis] # 使用 OAuth2 社交登录 pip install fastapi-fullauth[sqlmodel,oauth] # 全部 pip install fastapi-fullauth[all] ``` ## 快速开始 ``` from fastapi import FastAPI from fastapi_fullauth import FullAuth, FullAuthConfig from fastapi_fullauth.adapters.sqlmodel import SQLModelAdapter app = FastAPI() fullauth = FullAuth( adapter=SQLModelAdapter(session_maker=session_maker, user_model=User), config=FullAuthConfig(SECRET_KEY="your-secret-key"), ) fullauth.init_app(app) ``` 至此,所有认证路由已自动注册在 `/api/v1/auth/` 下。 在开发环境中省略 `config` 将生成随机密钥(重启后令牌失效)。 ### 可组合的路由器 排除你不需要的路由器: ``` fullauth.init_app(app, exclude_routers=["admin"]) ``` 或手动连接路由器以获得完全控制: ``` app = FastAPI() fullauth.bind(app) # required for dependencies to work app.include_router(fullauth.auth_router, prefix="/api/v1/auth") app.include_router(fullauth.profile_router, prefix="/api/v1/auth") fullauth.init_middleware(app) ``` | 路由器 | 路由 | |--------|------| | `auth_router` | 注册、登录、登出、刷新 | | `profile_router` | 我、已验证我、更新资料、删除账户、修改密码 | | `verify_router` | 邮箱验证、密码重置 | | `admin_router` | 分配/移除角色与权限(超级用户) | | `oauth_router` | OAuth 提供者路由(仅当配置时) | `fullauth.init_app(app)` 会包含所有路由。如需细粒度控制,可单独使用各路由器。 ## 路由 | 方法 | 路径 | 描述 | |--------|------|-------------| | `POST` | `/auth/register` | 创建新用户 | | `POST` | `/auth/login` | 认证并获取令牌 | | `POST` | `/auth/logout` | 黑名单令牌 | | `POST` | `/auth/refresh` | 轮换令牌对 | | `GET` | `/auth/me` | 获取当前用户 | | `GET` | `/auth/me/verified` | 仅限已验证用户 | | `PATCH` | `/auth/me` | 更新资料 | | `DELETE` | `/auth/me` | 删除账户 | | `POST` | `/auth/change-password` | 修改密码 | | `POST` | `/auth/verify-email/request` | 请求验证邮件 | | `POST` | `/auth/verify-email/confirm` | 确认邮箱 | | `POST` | `/auth/password-reset/request` | 请求密码重置 | | `POST` | `/auth/password-reset/confirm` | 重置密码 | | `POST` | `/auth/admin/assign-role` | 分配角色(超级用户) | | `POST` | `/auth/admin/remove-role` | 移除角色(超级用户) | | `POST` | `/auth/admin/assign-permission` | 为角色分配权限(超级用户) | | `POST` | `/auth/admin/remove-permission` | 从角色移除权限(超级用户) | | `GET` | `/auth/admin/role-permissions/{role}` | 列出角色权限(超级用户) | 启用 OAuth 后,额外路由将注册在 `/auth/oauth/` 下。所有路由默认以 `/api/v1` 为前缀。 ## 自定义用户模式 定义你的模型与模式,并显式传递给适配器: ``` from sqlmodel import Field, Relationship from fastapi_fullauth import FullAuth, FullAuthConfig, UserSchema, CreateUserSchema from fastapi_fullauth.adapters.sqlmodel import SQLModelAdapter from fastapi_fullauth.adapters.sqlmodel.models.base import UserBase, RefreshTokenRecord from fastapi_fullauth.adapters.sqlmodel.models.role import Role, UserRoleLink class User(UserBase, table=True): __tablename__ = "fullauth_users" display_name: str = Field(default="", max_length=100) phone: str = Field(default="", max_length=20) roles: list[Role] = Relationship(link_model=UserRoleLink) refresh_tokens: list[RefreshTokenRecord] = Relationship() class MyUserSchema(UserSchema): display_name: str = "" phone: str = "" class MyCreateSchema(CreateUserSchema): display_name: str = "" fullauth = FullAuth( adapter=SQLModelAdapter( session_maker, user_model=User, user_schema=MyUserSchema, create_user_schema=MyCreateSchema, ), config=FullAuthConfig(SECRET_KEY="..."), ) ``` 在自定义字段上获得完整的 IDE 自动补全与类型检查。使用 `get_current_user_dependency()` 获取类型化依赖: ``` from typing import Annotated from fastapi import Depends from fastapi_fullauth.dependencies import get_current_user_dependency MyCurrentUser = Annotated[MyUserSchema, Depends(get_current_user_dependency(MyUserSchema))] @app.get("/profile") async def profile(user: MyCurrentUser): return {"name": user.display_name} # IDE knows this field exists ``` ## 保护路由 ``` from fastapi import Depends from fastapi_fullauth.dependencies import CurrentUser, VerifiedUser, SuperUser, require_role @app.get("/profile") async def profile(user: CurrentUser): return user @app.get("/dashboard") async def dashboard(user: VerifiedUser): return {"email": user.email} @app.delete("/admin/users/{id}") async def delete_user(user: SuperUser): ... @app.get("/editor") async def editor_panel(user=Depends(require_role("editor"))): ... ``` ## OAuth2 社交登录 ``` from fastapi_fullauth import FullAuth, FullAuthConfig from fastapi_fullauth.oauth.google import GoogleOAuthProvider from fastapi_fullauth.oauth.github import GitHubOAuthProvider fullauth = FullAuth( adapter=adapter, config=FullAuthConfig(SECRET_KEY="..."), providers=[ GoogleOAuthProvider( client_id="your-google-client-id", client_secret="your-google-secret", redirect_uris=[ "http://localhost:3000/auth/callback", "https://myapp.com/auth/callback", ], ), GitHubOAuthProvider( client_id="your-github-client-id", client_secret="your-github-secret", redirect_uris=["http://localhost:3000/auth/callback"], ), ], ) ``` 需要 `httpx`:`pip install fastapi-fullauth[oauth]` ## 事件钩子 ``` async def welcome(user): await send_email(user.email, "Welcome!") async def send_verify(email, token): await send_email(email, f"Verify: https://myapp.com/verify?token={token}") fullauth.hooks.on("after_register", welcome) fullauth.hooks.on("send_verification_email", send_verify) ``` 事件包括:`after_register`、`after_login`、`after_logout`、`after_password_change`、`after_password_reset`、`after_email_verify`、`send_verification_email`、`send_password_reset_email`、`after_oauth_login` ## 配置 通过 `FullAuthConfig` 对象或设置 `FULLAUTH_` 前缀的环境变量进行配置。 ``` fullauth = FullAuth( adapter=adapter, config=FullAuthConfig( SECRET_KEY="...", ACCESS_TOKEN_EXPIRE_MINUTES=60, API_PREFIX="/api/v2", LOGIN_FIELD="username", PASSWORD_HASH_ALGORITHM="bcrypt", BLACKLIST_BACKEND="redis", REDIS_URL="redis://localhost:6379/0", AUTH_RATE_LIMIT_ENABLED=True, TRUSTED_PROXY_HEADERS=["X-Forwarded-For"], ), ) ``` 参见 [配置文档](https://mdfarhankc.github.io/fastapi-fullauth/configuration/) 了解所有选项。 ## AI 友好文档 如果你在使用 AI 编码助手?请使用我们的 LLM 优化文档: - **[llms.txt](https://mdfarhankc.github.io/fastapi-fullauth/llms.txt)** — 简洁概览,包含所有文档页面的链接 - **[llms-full.txt](https://mdfarhankc.github.io/fastapi-fullauth/llms-full.txt)** — 单个文件中的完整文档 适用于 Claude、Cursor、Copilot 以及任何接受文档 URL 的工具。 ## 开发 ``` git clone https://github.com/mdfarhankc/fastapi-fullauth.git cd fastapi-fullauth uv sync --dev --extra sqlalchemy --extra sqlmodel uv run pytest tests/ -v # 运行示例 uv run uvicorn examples.sqlmodel_app.main:app --reload ``` ## 许可证 MIT
标签:API 认证, Argon2id, AV绕过, bcrypt, FastAPI, FastAPI 中间件, FastAPI 插件, JWT, OAuth2, Python 认证库, RBAC, SEO: FastAPI 认证, SEO: JWT FastAPI, SEO: 异步认证, SEO: 生产级认证, SSO, Token 黑名单, Web 认证, 令牌轮换, 会话管理, 刷新令牌, 可插拔, 后端认证, 基于角色的访问控制, 安全令牌, 密码哈希, 密钥轮换, 异步原生, 授权, 搜索引擎查询, 生产级, 社交登录, 认证, 访问令牌, 身份提供者, 逆向工具, 透明重哈希, 邮箱验证, 重放攻击防护