geo/.qoder/repowiki/zh/content/API接口文档/认证接口.md

413 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 认证接口
<cite>
**本文档引用的文件**
- [backend/app/api/auth.py](file://backend/app/api/auth.py)
- [backend/app/schemas/auth.py](file://backend/app/schemas/auth.py)
- [backend/app/services/auth.py](file://backend/app/services/auth.py)
- [backend/app/models/user.py](file://backend/app/models/user.py)
- [backend/app/api/deps.py](file://backend/app/api/deps.py)
- [backend/app/config.py](file://backend/app/config.py)
- [backend/app/main.py](file://backend/app/main.py)
- [backend/app/database.py](file://backend/app/database.py)
- [tests/test_auth.py](file://tests/test_auth.py)
- [backend/requirements.txt](file://backend/requirements.txt)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件为认证系统的完整API文档覆盖以下接口
- 用户注册:/api/v1/auth/register
- 用户登录:/api/v1/auth/login
- 获取当前用户:/api/v1/auth/me
文档详细说明每个接口的请求参数、响应格式、状态码、错误处理以及JWT令牌生成机制、认证流程与安全考虑并提供认证中间件使用指南与最佳实践。
## 项目结构
后端采用FastAPI + SQLAlchemy异步ORM + PostgreSQL + Redis的架构认证模块位于backend/app/api/auth.py配合服务层、模型层与依赖注入实现。
```mermaid
graph TB
subgraph "后端应用"
A["FastAPI 应用<br/>路由注册"]
B["认证路由<br/>/api/v1/auth/*"]
C["认证服务<br/>密码哈希/校验/JWT"]
D["数据库会话<br/>AsyncSession"]
E["用户模型<br/>SQLAlchemy ORM"]
F["认证依赖<br/>OAuth2PasswordBearer"]
end
A --> B
B --> C
B --> D
C --> D
D --> E
F --> C
F --> D
```
图表来源
- [backend/app/main.py:38](file://backend/app/main.py#L38)
- [backend/app/api/auth.py:10](file://backend/app/api/auth.py#L10)
- [backend/app/services/auth.py:13](file://backend/app/services/auth.py#L13)
- [backend/app/database.py:23](file://backend/app/database.py#L23)
- [backend/app/models/user.py:11](file://backend/app/models/user.py#L11)
- [backend/app/api/deps.py:13](file://backend/app/api/deps.py#L13)
章节来源
- [backend/app/main.py:38](file://backend/app/main.py#L38)
- [backend/app/api/auth.py:10](file://backend/app/api/auth.py#L10)
## 核心组件
- 路由器:在主应用中注册认证路由前缀为/api/v1/auth
- 认证服务:提供密码哈希/校验、JWT生成/校验、用户注册与认证
- 数据模型:用户表结构,包含邮箱、密码哈希、计划等级、配额等字段
- 依赖注入OAuth2PasswordBearer用于从Authorization头提取Bearer令牌get_current_user解析并验证JWT加载当前用户
- 配置JWT密钥与过期时间、数据库连接等
章节来源
- [backend/app/api/auth.py:10](file://backend/app/api/auth.py#L10)
- [backend/app/services/auth.py:13](file://backend/app/services/auth.py#L13)
- [backend/app/models/user.py:11](file://backend/app/models/user.py#L11)
- [backend/app/api/deps.py:13](file://backend/app/api/deps.py#L13)
- [backend/app/config.py:9](file://backend/app/config.py#L9)
## 架构总览
认证系统遵循“请求-服务-模型-数据库”的分层设计使用OAuth2 Bearer令牌进行无状态认证。
```mermaid
sequenceDiagram
participant 客户端 as "客户端"
participant 路由 as "认证路由"
participant 服务 as "认证服务"
participant 数据库 as "数据库"
participant 依赖 as "认证依赖"
客户端->>路由 : POST /api/v1/auth/register
路由->>服务 : 注册用户(邮箱/密码/姓名)
服务->>数据库 : 查询邮箱是否已存在
数据库-->>服务 : 结果
服务->>服务 : 哈希密码
服务->>数据库 : 创建用户记录
数据库-->>服务 : 新用户对象
服务-->>路由 : 返回UserResponse
路由-->>客户端 : 201 Created + UserResponse
客户端->>路由 : POST /api/v1/auth/login
路由->>服务 : 认证(邮箱/密码)
服务->>数据库 : 查询用户
数据库-->>服务 : 用户或None
服务->>服务 : 校验密码
服务->>服务 : 生成JWT(access_token)
服务-->>路由 : 返回TokenResponse
路由-->>客户端 : 200 OK + TokenResponse
客户端->>依赖 : GET /api/v1/auth/me (Authorization : Bearer)
依赖->>依赖 : 解析并验证JWT
依赖->>数据库 : 按ID查询用户
数据库-->>依赖 : 用户对象
依赖-->>客户端 : 200 OK + UserResponse
```
图表来源
- [backend/app/api/auth.py:13](file://backend/app/api/auth.py#L13)
- [backend/app/api/auth.py:22](file://backend/app/api/auth.py#L22)
- [backend/app/api/auth.py:40](file://backend/app/api/auth.py#L40)
- [backend/app/services/auth.py:37](file://backend/app/services/auth.py#L37)
- [backend/app/services/auth.py:55](file://backend/app/services/auth.py#L55)
- [backend/app/api/deps.py:16](file://backend/app/api/deps.py#L16)
## 详细组件分析
### 用户注册接口 /api/v1/auth/register
- 方法与路径POST /api/v1/auth/register
- 请求体模型UserRegister
- 字段email邮箱、password字符串最小长度8、name字符串1-100
- 响应模型UserResponse
- 字段idUUID、email字符串、name可空、plan字符串默认"free"、max_queries整数默认5、is_active布尔默认true、created_at时间戳
- 成功响应201 Created
- 错误响应:
- 400 Bad Request当邮箱已被注册时返回错误详情
- 处理流程:
- 调用注册服务,检查邮箱唯一性
- 对密码进行哈希处理
- 写入数据库并返回新用户信息
```mermaid
flowchart TD
Start(["请求进入"]) --> Validate["校验请求体<br/>邮箱/密码/姓名"]
Validate --> CheckDup{"邮箱已存在?"}
CheckDup --> |是| Return400["返回400错误<br/>邮箱已注册"]
CheckDup --> |否| HashPwd["哈希密码"]
HashPwd --> Create["创建用户记录"]
Create --> Commit["提交事务"]
Commit --> Refresh["刷新用户对象"]
Refresh --> Return201["返回201 + UserResponse"]
```
图表来源
- [backend/app/api/auth.py:13](file://backend/app/api/auth.py#L13)
- [backend/app/services/auth.py:37](file://backend/app/services/auth.py#L37)
- [backend/app/schemas/auth.py:7](file://backend/app/schemas/auth.py#L7)
- [backend/app/schemas/auth.py:18](file://backend/app/schemas/auth.py#L18)
章节来源
- [backend/app/api/auth.py:13](file://backend/app/api/auth.py#L13)
- [backend/app/schemas/auth.py:7](file://backend/app/schemas/auth.py#L7)
- [backend/app/schemas/auth.py:18](file://backend/app/schemas/auth.py#L18)
- [backend/app/services/auth.py:37](file://backend/app/services/auth.py#L37)
- [tests/test_auth.py:26](file://tests/test_auth.py#L26)
- [tests/test_auth.py:43](file://tests/test_auth.py#L43)
请求示例
- POST /api/v1/auth/register
- 请求体JSON
- email: "string"
- password: "string(≥8)"
- name: "string(1-100)"
响应示例
- 201 Created
- 响应体JSON
- id: "uuid"
- email: "string"
- name: "string|null"
- plan: "string"
- max_queries: integer
- is_active: boolean
- created_at: "datetime"
状态码
- 201 Created注册成功
- 400 Bad Request邮箱已注册
错误处理
- 当服务层抛出ValueError如邮箱重复路由捕获并返回400
### 用户登录接口 /api/v1/auth/login
- 方法与路径POST /api/v1/auth/login
- 请求体模型UserLogin
- 字段email邮箱、password字符串
- 响应模型TokenResponse
- 字段access_token字符串、token_type字符串固定为"bearer"、userUserResponse
- 成功响应200 OK
- 错误响应:
- 401 Unauthorized邮箱或密码不正确携带WWW-Authenticate: Bearer头
- 处理流程:
- 使用邮箱查询用户
- 校验密码哈希
- 生成JWT令牌含过期时间返回access_token与用户信息
```mermaid
sequenceDiagram
participant 客户端 as "客户端"
participant 路由 as "登录路由"
participant 服务 as "认证服务"
participant 数据库 as "数据库"
客户端->>路由 : POST /api/v1/auth/login
路由->>服务 : authenticate_user(邮箱, 密码)
服务->>数据库 : 查询用户
数据库-->>服务 : 用户或None
服务->>服务 : 校验密码
alt 用户不存在或密码错误
服务-->>路由 : None
路由-->>客户端 : 401 Unauthorized
else 登录成功
服务-->>路由 : User对象
路由->>服务 : create_access_token({sub : userId})
服务-->>路由 : access_token
路由-->>客户端 : 200 OK + TokenResponse
end
```
图表来源
- [backend/app/api/auth.py:22](file://backend/app/api/auth.py#L22)
- [backend/app/api/auth.py:24](file://backend/app/api/auth.py#L24)
- [backend/app/services/auth.py:55](file://backend/app/services/auth.py#L55)
- [backend/app/services/auth.py:24](file://backend/app/services/auth.py#L24)
章节来源
- [backend/app/api/auth.py:22](file://backend/app/api/auth.py#L22)
- [backend/app/api/auth.py:24](file://backend/app/api/auth.py#L24)
- [backend/app/schemas/auth.py:13](file://backend/app/schemas/auth.py#L13)
- [backend/app/schemas/auth.py:30](file://backend/app/schemas/auth.py#L30)
- [backend/app/services/auth.py:55](file://backend/app/services/auth.py#L55)
- [backend/app/services/auth.py:24](file://backend/app/services/auth.py#L24)
- [tests/test_auth.py:62](file://tests/test_auth.py#L62)
- [tests/test_auth.py:76-84](file://tests/test_auth.py#L76-L84)
请求示例
- POST /api/v1/auth/login
- 请求体JSON
- email: "string"
- password: "string"
响应示例
- 200 OK
- 响应体JSON
- access_token: "string"
- token_type: "bearer"
- user: {
id: "uuid"
email: "string"
name: "string|null"
plan: "string"
max_queries: integer
is_active: boolean
created_at: "datetime"
}
状态码
- 200 OK登录成功
- 401 Unauthorized邮箱或密码不正确
安全考虑
- 密码使用BCrypt哈希存储
- JWT使用HS256算法与密钥签名过期时间由配置控制
- 登录失败返回统一错误消息,避免泄露账户存在性细节
### 获取当前用户接口 /api/v1/auth/me
- 方法与路径GET /api/v1/auth/me
- 权限要求需要Bearer令牌Authorization: Bearer <token>
- 依赖注入get_current_user
- 通过OAuth2PasswordBearer从Authorization头提取令牌
- 校验JWT并解析sub用户ID
- 从数据库按ID查询用户并返回
- 响应模型UserResponse
- 成功响应200 OK
- 错误响应:
- 401 Unauthorized令牌无效、过期或用户不存在
```mermaid
sequenceDiagram
participant 客户端 as "客户端"
participant 依赖 as "get_current_user"
participant 服务 as "verify_token"
participant 数据库 as "数据库"
客户端->>依赖 : GET /api/v1/auth/me (Authorization : Bearer)
依赖->>依赖 : 从Authorization头提取token
依赖->>服务 : verify_token(token)
服务-->>依赖 : payload(sub=userId)
依赖->>数据库 : 查询用户by id
数据库-->>依赖 : 用户或None
alt 令牌无效/用户不存在
依赖-->>客户端 : 401 Unauthorized
else 成功
依赖-->>客户端 : 200 OK + UserResponse
end
```
图表来源
- [backend/app/api/deps.py:16](file://backend/app/api/deps.py#L16)
- [backend/app/api/deps.py:27](file://backend/app/api/deps.py#L27)
- [backend/app/services/auth.py:32](file://backend/app/services/auth.py#L32)
- [backend/app/api/auth.py:40](file://backend/app/api/auth.py#L40)
章节来源
- [backend/app/api/auth.py:40](file://backend/app/api/auth.py#L40)
- [backend/app/api/deps.py:16](file://backend/app/api/deps.py#L16)
- [backend/app/api/deps.py:27](file://backend/app/api/deps.py#L27)
- [backend/app/services/auth.py:32](file://backend/app/services/auth.py#L32)
- [tests/test_auth.py:88](file://tests/test_auth.py#L88)
- [tests/test_auth.py:99](file://tests/test_auth.py#L99)
请求示例
- GET /api/v1/auth/me
- 请求头:
- Authorization: "Bearer <access_token>"
响应示例
- 200 OK
- 响应体JSONUserResponse
状态码
- 200 OK成功获取当前用户
- 401 Unauthorized未提供有效令牌或令牌无效
## 依赖分析
- 外部库依赖FastAPI、SQLAlchemy异步、Pydantic、python-jose、passlib、redis、apscheduler、playwright等
- 认证相关依赖OAuth2PasswordBearer、JWT编码/解码、BCrypt密码哈希
- 配置项JWT_SECRET、JWT_EXPIRE_HOURS、DATABASE_URL、REDIS_URL
```mermaid
graph LR
A["FastAPI 应用"] --> B["认证路由"]
B --> C["认证服务"]
C --> D["Passlib(Bcrypt)"]
C --> E["python-jose(JWT)"]
C --> F["SQLAlchemy 异步"]
F --> G["PostgreSQL"]
A --> H["CORS 中间件"]
A --> I["依赖注入容器"]
```
图表来源
- [backend/requirements.txt:2](file://backend/requirements.txt#L2)
- [backend/requirements.txt:16](file://backend/requirements.txt#L16)
- [backend/requirements.txt:17](file://backend/requirements.txt#L17)
- [backend/app/main.py:30](file://backend/app/main.py#L30)
- [backend/app/api/deps.py:13](file://backend/app/api/deps.py#L13)
- [backend/app/services/auth.py:13](file://backend/app/services/auth.py#L13)
章节来源
- [backend/requirements.txt:2](file://backend/requirements.txt#L2)
- [backend/requirements.txt:16](file://backend/requirements.txt#L16)
- [backend/requirements.txt:17](file://backend/requirements.txt#L17)
- [backend/app/main.py:30](file://backend/app/main.py#L30)
- [backend/app/api/deps.py:13](file://backend/app/api/deps.py#L13)
- [backend/app/services/auth.py:13](file://backend/app/services/auth.py#L13)
## 性能考虑
- 数据库访问:注册与登录均执行单次查询,使用异步会话减少阻塞
- 密码哈希BCrypt成本因子默认设置平衡安全性与性能
- JWT过期可通过配置调整过期时间建议根据业务场景权衡
- 缓存策略当前未对用户信息做缓存可在高频读取场景引入Redis缓存
## 故障排除指南
- 注册失败400确认邮箱唯一性检查请求体字段类型与长度
- 登录失败401确认邮箱与密码正确检查JWT密钥与过期时间配置
- 获取当前用户失败401确认Authorization头格式为Bearer <token>;检查令牌是否过期
- 数据库连接问题检查DATABASE_URL配置确保PostgreSQL服务可用
- CORS跨域问题确认前端域名已在CORS允许列表中
章节来源
- [tests/test_auth.py:43](file://tests/test_auth.py#L43)
- [tests/test_auth.py:76-84](file://tests/test_auth.py#L76-L84)
- [tests/test_auth.py:99](file://tests/test_auth.py#L99)
- [backend/app/config.py:7](file://backend/app/config.py#L7)
- [backend/app/main.py:30](file://backend/app/main.py#L30)
## 结论
认证系统基于FastAPI与SQLAlchemy异步ORM构建采用OAuth2 Bearer令牌与JWT实现无状态认证。注册与登录流程清晰错误处理明确具备良好的扩展性与安全性基础。建议在生产环境完善令牌刷新策略、速率限制与审计日志并定期轮换JWT密钥。
## 附录
### JWT令牌生成机制
- 签名算法HS256
- 过期时间由配置JWT_EXPIRE_HOURS决定
- 载荷包含sub用户ID与exp过期时间
- 生成流程在登录成功后调用create_access_token(data={"sub": str(user.id)})
章节来源
- [backend/app/services/auth.py:24](file://backend/app/services/auth.py#L24)
- [backend/app/services/auth.py:26](file://backend/app/services/auth.py#L26)
- [backend/app/config.py:10](file://backend/app/config.py#L10)
### 认证中间件使用指南与最佳实践
- 在需要保护的路由上使用依赖注入Depends(get_current_user)
- 前端在每次请求中携带Authorization: Bearer <access_token>
- 生产环境务必设置安全的JWT_SECRET并启用HTTPS
- 建议实现令牌刷新与登出机制,避免长期持有高权限令牌
- 对登录失败与敏感操作增加速率限制与日志审计
章节来源
- [backend/app/api/deps.py:16](file://backend/app/api/deps.py#L16)
- [backend/app/api/auth.py:40](file://backend/app/api/auth.py#L40)
- [backend/app/config.py:9](file://backend/app/config.py#L9)