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
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()的测试逻辑
注意事项
-
生产环境安全:
- 测试验证码仅用于开发/测试环境
- 生产环境应通过环境变量禁用或使用更安全的机制
-
日志记录:
- 使用测试验证码时会记录日志,便于调试
- 日志格式:
使用测试验证码: phone=xxx, purpose=login
-
后续优化:
- 考虑通过环境变量
SMS_TEST_CODE_ENABLED控制是否启用 - 考虑支持多个测试验证码(如
6666,8888)
- 考虑通过环境变量