# 用户登录体系重构方案 > **创建时间**:2025-01-14 > **状态**:已完成 --- ## 变更概述 将用户登录体系从传统的邮箱/密码登录重构为手机号验证码登录和微信扫码登录,支持多种账号绑定方式。 --- ## 核心变更 ### 1. 数据库层 #### users 表新增字段 ```sql -- 手机号相关 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 表 ```sql 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 # 密码修改(后期可选支持) ``` --- ## 技术实现 ### 用户名自动生成 ```python 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 实现分布式限流: ```python # 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 ``` --- ## 环境变量配置 ```env # 短信服务(阿里云) 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 ``` --- ## 依赖安装 ```txt # 短信服务 aliyun-python-sdk-core==2.13.36 aliyun-python-sdk-dysmsapi==3.0.0 # 微信 SDK wechatpy==1.8.18 # Redis redis==4.5.1 ``` --- ## 文档输出 ### 创建的文档 1. `docs/需求/backend/04-services/sms-service.md` - 短信验证码服务文档 2. `docs/需求/backend/04-services/wechat-service.md` - 微信登录服务文档 3. `docs/计划/用户登录体系重构.md` - 执行计划文档 4. `docs/方案/用户登录体系重构.md` - 本方案文档 ### 修改的文档 1. `docs/需求/backend/04-services/user-service.md` - 用户管理服务文档(v2.0) --- ## 后续优化 1. 支持邮箱验证码登录 2. 支持 Google/Apple 第三方登录 3. 支持国际短信(多国区号) 4. 验证码图形验证码(防机器人) 5. 微信小程序登录支持 --- **文档版本**:v1.0 **创建时间**:2025-01-14