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.
 

3.3 KiB

修复短信验证码测试绕过逻辑

日期: 2026-01-27
类型: Bug 修复
影响范围: 短信验证码服务

问题描述

手机号登录接口 /api/v1/auth/login/phone 使用测试验证码 6666 时仍然提示"验证码不存在或已过期"。

根本原因

SmsService.verify_code() 方法缺少测试验证码绕过逻辑,直接查询数据库导致:

  • 如果数据库中没有 6666 的记录 → 提示"验证码不存在或已过期"
  • 如果记录已过期 → 同样提示过期

UserService.bind_phone() 方法中有正确的测试验证码逻辑,导致行为不一致。

解决方案

SmsService.verify_code() 方法开头添加测试验证码绕过逻辑:

async def verify_code(
    self,
    phone: str,
    country_code: str,
    code: str,
    purpose: SmsPurpose = SmsPurpose.LOGIN
) -> bool:
    """验证验证码"""
    
    # 测试验证码绕过(开发阶段)
    if code == "6666":
        logger.info(f"使用测试验证码: phone={phone}, purpose={purpose.to_string()}")
        return True
    
    # 正常验证流程...
    verification_code = await self.repository.get_valid_code(...)
    ...

修改文件

  • server/app/services/sms_service.py
    • verify_code() 方法开头添加测试验证码判断
    • 记录测试验证码使用日志

测试验证

测试用例 1:使用测试验证码登录

curl -X POST http://localhost:8000/api/v1/auth/login/phone \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "13800138000",
    "countryCode": "+86",
    "code": "6666"
  }'

预期结果

  • 登录成功
  • 返回用户信息和 token
  • 日志显示"使用测试验证码"

测试用例 2:使用真实验证码登录

# 1. 发送验证码
curl -X POST http://localhost:8000/api/v1/auth/sms/send \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "13800138000",
    "countryCode": "+86",
    "purpose": "login"
  }'

# 2. 使用真实验证码登录
curl -X POST http://localhost:8000/api/v1/auth/login/phone \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "13800138000",
    "countryCode": "+86",
    "code": "123456"
  }'

预期结果

  • 验证码正确时登录成功
  • 验证码错误时提示"验证码错误"
  • 验证码过期时提示"验证码不存在或已过期"

影响范围

受益接口

  • POST /api/v1/auth/login/phone - 手机号登录
  • POST /api/v1/auth/sms/verify - 验证码验证(可选)

行为变更

  • 测试验证码 6666 现在可以正常使用
  • 不需要先调用 /auth/sms/send 发送验证码
  • 统一了 verify_code()bind_phone() 的测试逻辑

注意事项

  1. 生产环境安全

    • 测试验证码仅用于开发/测试环境
    • 生产环境应通过环境变量禁用或使用更安全的机制
  2. 日志记录

    • 使用测试验证码时会记录日志,便于调试
    • 日志格式:使用测试验证码: phone=xxx, purpose=login
  3. 后续优化

    • 考虑通过环境变量 SMS_TEST_CODE_ENABLED 控制是否启用
    • 考虑支持多个测试验证码(如 6666, 8888

相关文档