一个完整的 OAuth2 授权码模式 (Authorization Code Flow) 演示项目,展示了 OAuth2 认证流程中三个核心角色的交互。
本项目采用三服务器架构,完整模拟真实 OAuth2 认证流程:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Client App │ │ Authorization │ │ Resource │
│ (端口 8001) │◄───────►│ Server │◄───────►│ Server │
│ │ │ (端口 8000) │ │ (端口 8002) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
| 服务器 | 端口 | 职责 |
|---|---|---|
| Authorization Server | 8000 | 用户认证、授权、颁发令牌 |
| Client Application | 8001 | 第三方应用,发起授权请求 |
| Resource Server | 8002 | 保护用户资源,验证令牌 |
- Python 3.14+
- FastAPI - 现代高性能 Web 框架
- Authlib - OAuth2 协议实现
- Uvicorn - ASGI 服务器
- httpx - 异步 HTTP 客户端
# 使用 uv (推荐)
uv sync
# 或使用 pip
pip install -e .# 同时启动三个服务器
python run.py或分别启动各服务器:
# 终端 1 - 授权服务器
uvicorn oauth_server:app --host 0.0.0.0 --port 8000
# 终端 2 - 客户端应用
uvicorn oauth_client:app --host 0.0.0.0 --port 8001
# 终端 3 - 资源服务器
uvicorn resource_server:app --host 0.0.0.0 --port 8002┌──────────┐ ┌──────────┐
│ │ │ │
│ User │ │ Client │
│ │ │ │
└────┬─────┘ └────┬─────┘
│ │
│ 1. 点击"使用 OAuth2 登录" │
│────────────────────────────────────────────────►│
│ │
│ 2. 重定向到授权服务器 │
│◄────────────────────────────────────────────────│
│ GET /authorize?... │
│ │
│ 3. 用户登录并授权 │
│────────────────────────────────────────────────►│
│ POST /authorize │
│ │
│ 4. 重定向回客户端 (带授权码) │
│◄────────────────────────────────────────────────│
│ GET /callback?code=... │
│ │
│ 5. 客户端用授权码换取令牌 │
│ POST /token │
│ ◄─────────────────────────────│
│ │
│ 6. 客户端用令牌获取用户信息 │
│ GET /userinfo │
│ ◄─────────────────────────────│
│ │
│ 7. 显示用户信息 │
│◄────────────────────────────────────────────────│
│ │
| 端点 | 方法 | 描述 |
|---|---|---|
/ |
GET | 授权服务器首页 |
/authorize |
GET | 授权端点,展示登录页面 |
/authorize |
POST | 处理用户登录和授权 |
/token |
POST | 令牌端点,授权码换取令牌 |
/introspect |
POST | 令牌自省端点,验证令牌有效性 |
| 端点 | 方法 | 描述 |
|---|---|---|
/ |
GET | 客户端首页,登录入口 |
/login |
GET | 发起 OAuth2 授权请求 |
/callback |
GET | 授权回调,处理授权码 |
/profile |
GET | 用户信息页面 |
| 端点 | 方法 | 描述 |
|---|---|---|
/userinfo |
GET | 获取用户信息 (需要 Bearer Token) |
| 用户名 | 密码 | 用户 ID |
|---|---|---|
| admin | admin123 | 1 |
| user | user123 | 2 |
预配置的测试客户端:
client_id = "demo_client"
client_secret = "demo_secret"
redirect_uri = "http://localhost:8001/callback"- 启动所有服务器
- 访问客户端应用: http://localhost:8001
- 点击 "使用 OAuth2 登录"
- 使用测试账号登录 (admin/admin123)
- 授权客户端访问
- 自动跳转回客户端并显示用户信息
oauth2_server/
├── oauth_server.py # 授权服务器
├── oauth_client.py # 客户端应用
├── resource_server.py # 资源服务器
├── run.py # 启动脚本
├── templates/ # 授权服务器模板
│ ├── index.html
│ └── login.html
├── client_templates/ # 客户端模板
│ ├── client_index.html
│ └── profile.html
├── pyproject.toml # 项目配置
└── README.md # 本文件
- State 参数: 防止 CSRF 攻击
- 授权码短期有效: 授权码使用后立即失效
- 令牌过期: Access Token 1小时过期
- Refresh Token: 支持令牌刷新
- Redirect URI 验证: 严格验证重定向地址
详细的 OAuth2 授权码流程说明请参考: OAuth2_Authorization_Flow.md
MIT License