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.
 

5.0 KiB

用户登录体系重构计划

创建时间:2025-01-14
状态:待批准


需求背景

前期支持以下登录方式:

  1. 手机号 + 验证码登录(主要方式)
  2. 微信扫码登录(支持公众号和开放平台)

登录后可选绑定邮箱、修改用户名(仅一次)。


核心变更

1. 数据库层

users 表新增字段

-- 手机号相关
phone TEXT UNIQUE,
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(新建)

  • 发送验证码(10分钟有效期)
  • 验证验证码
  • 防刷机制(IP + 手机号限流)

WechatService(新建)

  • 生成微信登录二维码
  • 处理微信回调
  • 支持公众号和开放平台

UserService(重构)

  • 新增手机号登录
  • 新增微信登录
  • 新增账号绑定功能
  • 自动生成用户名:user_{timestamp}_{random4}

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              # 不再需要显式注册

执行步骤

Step 1: 数据库设计变更

  • 更新 docs/需求/backend/04-database-design.md
  • 添加 users 表字段变更说明
  • 添加 sms_verification_codes 表设计

Step 2: 创建 SmsService 文档

  • 创建 docs/需求/backend/04-services/sms-service.md
  • 定义核心方法
  • 定义防刷策略
  • 定义 API 接口

Step 3: 创建 WechatService 文档

  • 创建 docs/需求/backend/04-services/wechat-service.md
  • 定义微信登录流程
  • 定义公众号和开放平台配置
  • 定义 API 接口

Step 4: 更新 UserService 文档

  • 更新 docs/需求/backend/04-services/user-service.md
  • 新增手机号登录方法
  • 新增微信登录方法
  • 新增账号绑定方法
  • 新增用户名生成逻辑
  • 移除 register 方法

Step 5: 更新 API 设计文档

  • 更新 docs/需求/backend/05-api-design.md
  • 添加新增接口说明
  • 添加请求/响应示例

Step 6: 环境变量配置

  • 创建 server/.env.example
  • 添加短信服务配置
  • 添加微信公众号配置
  • 添加微信开放平台配置
  • 添加 Redis 配置

Step 7: 依赖管理

  • 更新 server/requirements.txt
  • 添加阿里云 SMS SDK
  • 添加 wechatpy
  • 添加 redis

技术细节

用户名生成规则

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

验证码防刷策略

  • 同一 IP 1分钟内最多发送 3 次
  • 同一手机号 1分钟内最多发送 1 次
  • 同一手机号 1小时内最多发送 5 次
  • 验证码有效期 10 分钟
  • 验证码使用后立即失效

微信登录流程

  1. 前端调用 /api/v1/auth/wechat/qrcode?platform=mp 获取二维码
  2. 用户扫码授权
  3. 微信回调服务器 /api/v1/auth/wechat/callback
  4. 服务器将用户信息存入 Redis(key: scene_id)
  5. 前端轮询 /api/v1/auth/wechat/result?scene_id=xxx 获取登录结果
  6. 返回 access_token 和 refresh_token

风险评估

高风险

  • 短信服务费用(需要设置每日发送上限)
  • 验证码被恶意刷取(已有防刷机制)

中风险

  • 微信登录回调失败(需要日志监控)
  • Redis 故障导致验证码丢失(需要降级方案)

低风险

  • 用户名冲突(时间戳 + 随机数保证唯一性)

后续优化

  1. 支持邮箱验证码登录
  2. 支持 Google/Apple 第三方登录
  3. 支持国际短信(多国区号)
  4. 验证码图形验证码(防机器人)

等待用户批准执行...