mdfarhankc/fastapi-fullauth
GitHub: mdfarhankc/fastapi-fullauth
为 FastAPI 提供生产级、原生异步的身份验证与授权库,覆盖完整的安全管控与可扩展能力。
Stars: 1 | Forks: 0
FastAPI FullAuth
适用于 FastAPI 的生产级、原生异步的身份验证与授权。
文档: 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 认证, 令牌轮换, 会话管理, 刷新令牌, 可插拔, 后端认证, 基于角色的访问控制, 安全令牌, 密码哈希, 密钥轮换, 异步原生, 授权, 搜索引擎查询, 生产级, 社交登录, 认证, 访问令牌, 身份提供者, 逆向工具, 透明重哈希, 邮箱验证, 重放攻击防护