# 认证接口

<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
  - 字段：id（UUID）、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"）、user（UserResponse）
- 成功响应：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
- 响应体JSON：UserResponse

状态码
- 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)