技术规范
概览
创建全面的技术规范,定义软件项目系统需求、架构、实施细节和验收标准。
何时使用
- 功能规格说明
- 系统设计文档
- 需求文档(PRD)
- 架构决策记录(ADR)
- 技术提案
- RFC(征求修改意见)
- API设计规范
- 数据库模式设计
技术规范模板
# 技术规范:[功能名称]
**文档状态:** 草稿 | 审核 | 批准 | 实施
**版本:** 1.0
**作者:** 约翰·多伊
**日期:** 2025-01-15
**审核者:** 简·史密斯,鲍勃·约翰逊
**最后更新:** 2025-01-15
## 执行摘要
简要2-3句概述此规范涵盖的内容及构建原因。
**问题:** 我们正在解决什么问题?
**解决方案:** 高层次的解决方案描述
**影响:** 预期的业务/用户影响
---
## 1. 背景
### 上下文
提供为什么需要此功能背景:
- 当前情况如何?
- 存在哪些痛点?
- 什么驱动了这一变化?
### 目标
- **主要目标:** 此功能的主要目标
- **次要目标:** 额外的好处
- **成功指标:** 我们将如何衡量成功
- 指标1:[描述] - 目标:[值]
- 指标2:[描述] - 目标:[值]
### 非目标
此规范明确不涵盖的内容:
- 非目标1
- 非目标2
- 未来的考虑(v1范围之外)
---
## 2. 需求
### 功能需求
#### FR-1:用户认证
**优先级:** P0(必须有)
**描述:** 用户必须能够使用电子邮件/密码进行认证
**验收标准:**
- [ ] 用户可以使用电子邮件和密码注册
- [ ] 用户可以使用凭据登录
- [ ] 用户收到电子邮件验证
- [ ] 用户可以重置忘记的密码
- [ ] 会话在7天不活动后过期
**依赖项:** 无
#### FR-2:社交登录
**优先级:** P1(应该有)
**描述:** 用户可以使用OAuth提供商进行认证
**验收标准:**
- [ ] 支持Google OAuth
- [ ] 支持GitHub OAuth
- [ ] 将社交账户链接到现有账户
- [ ] 取消链接社交账户
**依赖项:** FR-1
#### FR-3:双因素认证
**优先级:** P2(最好有)
**描述:** 可选的2FA增强安全性
**验收标准:**
- [ ] 在设置中启用/禁用2FA
- [ ] 支持TOTP(Google Authenticator,Authy)
- [ ] 备份代码生成
- [ ] 设备丢失时的恢复流程
**依赖项:** FR-1
### 非功能需求
#### 性能
- **响应时间:** API端点 < 200ms p95
- **吞吐量:** 支持每秒1000个请求
- **数据库查询:** < 50ms p95
- **页面加载:** 第一次内容绘制 < 1.5s
#### 可扩展性
- **并发用户:** 支持100,000名同时用户
- **数据增长:** 处理10M用户记录
- **水平扩展:** 支持10个应用实例
#### 安全性
- **认证:** 基于JWT的刷新令牌
- **密码哈希:** bcrypt 12轮
- **速率限制:** 每小时每IP 100个请求
- **数据加密:** 静态AES-256,传输中的TLS 1.3
#### 可用性
- **正常运行时间:** 99.9% SLA
- **恢复时间:** RTO < 4小时,RPO < 1小时
- **备份:** 每日自动备份,保留30天
#### 合规性
- GDPR合规(数据导出/删除)
- SOC 2 Type II要求
- PCI DSS(如果处理付款)
---
## 3. 系统架构
### 高层架构
┌─────────────┐ │ 客户端 │ │ (React应用) │ └──────┬──────┘ │ ▼ ┌─────────────┐ ┌──────────────┐ │ API网关 │────▶│ 认证服务 │ │ (Express) │ │ (Node.js) │ └──────┬──────┘ └──────┬───────┘ │ │ ▼ ▼ ┌─────────────┐ ┌──────────────┐ │用户服务 │ │ 数据库 │ │ (Node.js) │────▶│ (PostgreSQL) │ └─────────────┘ └──────────────┘ │ ▼ ┌─────────────┐ │ 缓存 │ │ (Redis) │ └─────────────┘
### 组件图
#### 前端(React)
- **登录页面:** 电子邮件/密码和社交登录
- **注册页面:** 用户注册与验证
- **设置页面:** 管理2FA和连接账户
- **组件:** 可重用的认证组件
#### 后端(Node.js/Express)
- **认证控制器:** 处理认证请求
- **用户控制器:** 管理用户数据
- **认证中间件:** 验证JWT令牌
- **速率限制器:** 防止滥用
#### 数据库(PostgreSQL)
- **users表:** 用户账户数据
- **sessions表:** 活跃会话
- **oauth_connections表:** 社交登录链接
#### 缓存(Redis)
- 会话存储
- 速率限制计数器
- 临时令牌(密码重置,电子邮件验证)
---
## 4. 数据模型
### 数据库模式
```sql
-- 用户表
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255),
email_verified BOOLEAN DEFAULT FALSE,
two_factor_enabled BOOLEAN DEFAULT FALSE,
two_factor_secret VARCHAR(32),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
last_login_at TIMESTAMP
);
-- OAuth连接
CREATE TABLE oauth_connections (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
provider VARCHAR(50) NOT NULL, -- 'google', 'github'
provider_user_id VARCHAR(255) NOT NULL,
access_token TEXT,
refresh_token TEXT,
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(provider, provider_user_id)
);
-- 会话
CREATE TABLE sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
token VARCHAR(255) UNIQUE NOT NULL,
expires_at TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
ip_address INET,
user_agent TEXT
);
-- 索引
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_sessions_token ON sessions(token);
CREATE INDEX idx_sessions_user_id ON sessions(user_id);
CREATE INDEX idx_oauth_user_id ON oauth_connections(user_id);
API数据模型
interface User {
id: string;
email: string;
emailVerified: boolean;
twoFactorEnabled: boolean;
createdAt: string;
updatedAt: string;
lastLoginAt?: string;
}
interface LoginRequest {
email: string;
password: string;
twoFactorCode?: string;
}
interface LoginResponse {
success: boolean;
token: string;
refreshToken: string;
user: User;
expiresIn: number;
}
interface RegisterRequest {
email: string;
password: string;
confirmPassword: string;
}
5. API设计
认证端点
POST /api/auth/register
描述: 注册新用户账户
请求:
{
"email": "user@example.com",
"password": "SecurePass123!",
"confirmPassword": "SecurePass123!"
}
响应(201):
{
"success": true,
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"emailVerified": false
},
"message": "验证电子邮件已发送"
}
错误:
- 400:无效的电子邮件格式
- 409:电子邮件已存在
- 422:密码太弱
POST /api/auth/login
描述: 认证用户并返回JWT令牌
请求:
{
"email": "user@example.com",
"password": "SecurePass123!",
"twoFactorCode": "123456"
}
响应(200):
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com"
},
"expiresIn": 3600
}
错误:
- 401:无效的凭据
- 403:账户锁定
- 428:需要2FA代码
速率限制
| 端点 | 限制 | 窗口 |
|---|---|---|
| POST /api/auth/login | 5次尝试 | 15分钟 |
| POST /api/auth/register | 3次尝试 | 1小时 |
| POST /api/auth/reset-password | 3次尝试 | 1小时 |
6. 实施计划
第1阶段:核心认证(第1-2周)
- [ ] 数据库模式设置
- [ ] 用户注册端点
- [ ] 电子邮件/密码登录
- [ ] JWT令牌生成
- [ ] 密码哈希
- [ ] 基本前端表单
第2阶段:电子邮件验证(第3周)
- [ ] 电子邮件服务集成
- [ ] 验证令牌生成
- [ ] 验证端点
- [ ] 电子邮件模板
- [ ] 重新发送验证电子邮件
第3阶段:社交登录(第4周)
- [ ] OAuth集成(Google)
- [ ] OAuth集成(GitHub)
- [ ] 账户链接
- [ ] 前端OAuth按钮
第4阶段:安全功能(第5周)
- [ ] 双因素认证
- [ ] 密码重置流程
- [ ] 速率限制
- [ ] 会话管理
- [ ] 安全头
第5阶段:测试和润色(第6周)
- [ ] 单元测试
- [ ] 集成测试
- [ ] E2E测试
- [ ] 安全审计
- [ ] 性能测试
- [ ] 文档
7. 测试策略
单元测试
- 密码哈希/验证
- JWT令牌生成/验证
- 输入验证
- 业务逻辑
覆盖率目标: 90%
集成测试
- API端点测试
- 数据库操作
- OAuth流程
- 电子邮件发送
覆盖率目标: 80%
E2E测试
- 完整的注册流程
- 使用电子邮件/密码登录
- 社交登录流程
- 密码重置流程
- 2FA设置和验证
覆盖率目标: 仅关键路径
性能测试
- 负载测试:1000个并发登录
- 压力测试:找到断点
- 数据库查询性能
8. 安全考虑
威胁
| 威胁 | 缓解 |
|---|---|
| 暴力破解 | 速率限制,账户锁定 |
| SQL注入 | 参数化查询,ORM |
| XSS | 输入清理,CSP头 |
| CSRF | CSRF令牌,SameSite cookie |
| 会话劫持 | 安全cookie,仅HTTPS |
| 密码泄露 | bcrypt哈希,密码强度 |
安全清单
- [ ] 强制HTTPS
- [ ] 安全头配置
- [ ] 实施速率限制
- [ ] 所有端点输入验证
- [ ] 防止SQL注入
- [ ] 防止XSS
- [ ] CSRF保护
- [ ] 安全密码存储
- [ ] 审计日志
9. 监控与可观测性
指标
- 认证成功率
- 失败登录尝试
- 平均登录时间
- 活跃会话
- 2FA采用率
警报
- 登录失败率 > 10%
- 数据库连接错误
- 电子邮件发送失败
- 速率限制超过 > 100次/小时
日志
// 日志结构
{
"timestamp": "2025-01-15T14:30:00Z",
"level": "info",
"event": "user_login",
"userId": "550e8400-...",
"ip": "192.168.1.1",
"userAgent": "Mozilla/5.0...",
"success": true,
"duration": 125
}
10. 风险与缓解
| 风险 | 概率 | 影响 | 缓解 |
|---|---|---|---|
| OAuth提供商停机 | 中等 | 高 | 回落到电子邮件登录 |
| 数据库迁移问题 | 低 | 高 | 在暂存环境中彻底测试 |
| 负载下的性能 | 中等 | 中等 | 负载测试,缓存 |
| 安全漏洞 | 低 | 严重 | 安全审计,渗透测试 |
11. 开放问题
- 我们是否应该支持无密码认证?
- 会话超时策略是什么?
- 我们需要魔法链接登录吗?
- 我们应该实现记住我功能吗?
12. 考虑的替代方案
替代方案1:使用Auth0
优点: 更快的实施,经过验证的安全 缺点: 成本,供应商锁定,自定义较少 决定: 为灵活性而内部构建
替代方案2:使用基于会话的认证而不是JWT
优点: 更简单的撤销,令牌大小较小 缺点: 难以扩展,CORS问题 决定: 使用JWT进行无状态扩展
13. 成功标准
发布标准
- [ ] 实现所有P0需求
- [ ] 安全审计通过
- [ ] 负载测试通过(1000个并发用户)
- [ ] 文档完成
- [ ] 实现90%测试覆盖率
发布后指标(第1周)
- < 1%认证错误率
- < 500ms平均登录时间
-
95%用户满意度(调查)
- 零安全事件
14. 参考资料
- OWASP认证备忘单
- JWT最佳实践
- OAuth 2.0规范
- 内部:认证RFC #123