You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.0 KiB
6.0 KiB
用户登录体系重构方案
创建时间:2025-01-14
状态:已完成
变更概述
将用户登录体系从传统的邮箱/密码登录重构为手机号验证码登录和微信扫码登录,支持多种账号绑定方式。
核心变更
1. 数据库层
users 表新增字段
-- 手机号相关
phone TEXT,
country_code TEXT DEFAULT '+86',
phone_verified BOOLEAN DEFAULT false,
-- 微信相关
wechat_openid TEXT,
wechat_unionid TEXT,
wechat_platform TEXT CHECK (wechat_platform IN ('mp', 'open')),
-- 用户名管理
username_changed BOOLEAN DEFAULT false,
-- 原有字段调整
email TEXT, -- 移除 NOT NULL
password_hash TEXT, -- 移除 NOT NULL
新增 sms_verification_codes 表
CREATE TABLE sms_verification_codes (
code_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
phone TEXT NOT NULL,
country_code TEXT NOT NULL DEFAULT '+86',
code TEXT NOT NULL,
purpose TEXT NOT NULL CHECK (purpose IN ('login', 'bind_phone')),
expires_at TIMESTAMPTZ NOT NULL,
verified BOOLEAN DEFAULT false,
ip_address INET,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
2. 服务层
新增 SmsService
职责:短信验证码发送和验证
核心方法:
send_verification_code()- 发送验证码verify_code()- 验证验证码clean_expired_codes()- 清理过期验证码
防刷策略:
- IP 限流:1分钟内最多 3 次
- 手机号限流:1分钟内最多 1 次,1小时内最多 5 次
- 验证码有效期:10 分钟
新增 WechatService
职责:微信登录和账号绑定
核心方法:
generate_qrcode()- 生成微信登录二维码handle_callback()- 处理微信回调get_login_result()- 前端轮询获取登录结果bind_wechat()- 绑定微信账号
支持平台:
mp:微信公众号open:微信开放平台
重构 UserService
新增方法:
login_with_phone()- 手机号验证码登录login_with_wechat()- 微信扫码登录bind_phone()- 绑定手机号bind_wechat()- 绑定微信bind_email()- 绑定邮箱update_username()- 修改用户名(仅一次)generate_username()- 自动生成用户名
移除方法:
register()- 不再需要显式注册
3. API 层
新增接口
POST /api/v1/auth/sms/send # 发送验证码
POST /api/v1/auth/login/phone # 手机号登录
GET /api/v1/auth/wechat/qrcode # 获取微信登录二维码
GET /api/v1/auth/wechat/result # 轮询登录结果
POST /api/v1/users/me/bind/phone # 绑定手机号
POST /api/v1/users/me/bind/wechat # 绑定微信
POST /api/v1/users/me/bind/email # 绑定邮箱
PUT /api/v1/users/me/username # 修改用户名
移除接口
POST /api/v1/auth/register # 不再需要显式注册
POST /api/v1/auth/login # 邮箱/密码登录(后期可选支持)
POST /api/v1/users/me/change-password # 密码修改(后期可选支持)
技术实现
用户名自动生成
import time
import random
import string
def generate_username():
timestamp = int(time.time())
random_suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=4))
return f"user_{timestamp}_{random_suffix}"
# 示例:user_1738012345_a3f9
验证码防刷
使用 Redis 实现分布式限流:
# IP 限流(1分钟内最多 3 次)
ip_key = f"sms:ip:{ip_address}"
ip_count = redis.get(ip_key)
if ip_count and int(ip_count) >= 3:
raise RateLimitError("发送过于频繁")
redis.incr(ip_key)
redis.expire(ip_key, 60)
# 手机号限流(1分钟内最多 1 次)
phone_key_1min = f"sms:phone:{country_code}:{phone}:1min"
if redis.get(phone_key_1min):
raise RateLimitError("验证码已发送")
redis.set(phone_key_1min, 1, ex=60)
# 手机号限流(1小时内最多 5 次)
phone_key_1hour = f"sms:phone:{country_code}:{phone}:1hour"
count = redis.incr(phone_key_1hour)
if count == 1:
redis.expire(phone_key_1hour, 3600)
if count > 5:
raise RateLimitError("今日发送次数已达上限")
微信登录流程
1. 前端请求二维码
GET /api/v1/auth/wechat/qrcode?platform=mp
2. 后端生成 scene_id,返回二维码 URL
3. 用户扫码授权
4. 微信回调后端
GET /api/v1/auth/wechat/callback?code=xxx&state=scene_id
5. 后端获取用户信息,存入 Redis
6. 前端轮询获取登录结果
GET /api/v1/auth/wechat/result?scene_id=xxx
7. 返回 JWT Token
环境变量配置
# 短信服务(阿里云)
SMS_ACCESS_KEY_ID=your_access_key_id
SMS_ACCESS_KEY_SECRET=your_access_key_secret
SMS_SIGN_NAME=道研组
SMS_TEMPLATE_CODE=SMS_123456789
# 微信公众号
WECHAT_MP_APPID=wx1234567890abcdef
WECHAT_MP_SECRET=your_mp_secret
WECHAT_MP_CALLBACK_URL=https://api.jointo.ai/api/v1/auth/wechat/callback
# 微信开放平台
WECHAT_OPEN_APPID=wx0987654321fedcba
WECHAT_OPEN_SECRET=your_open_secret
WECHAT_OPEN_CALLBACK_URL=https://api.jointo.ai/api/v1/auth/wechat/callback
# Redis
REDIS_URL=redis://localhost:6379/0
依赖安装
# 短信服务
aliyun-python-sdk-core==2.13.36
aliyun-python-sdk-dysmsapi==3.0.0
# 微信 SDK
wechatpy==1.8.18
# Redis
redis==4.5.1
文档输出
创建的文档
docs/需求/backend/04-services/sms-service.md- 短信验证码服务文档docs/需求/backend/04-services/wechat-service.md- 微信登录服务文档docs/计划/用户登录体系重构.md- 执行计划文档docs/方案/用户登录体系重构.md- 本方案文档
修改的文档
docs/需求/backend/04-services/user-service.md- 用户管理服务文档(v2.0)
后续优化
- 支持邮箱验证码登录
- 支持 Google/Apple 第三方登录
- 支持国际短信(多国区号)
- 验证码图形验证码(防机器人)
- 微信小程序登录支持
文档版本:v1.0
创建时间:2025-01-14