BookSystem/backend/auth/utils/redis_client.py
jayhgq 81972f1328 feat(auth): 添加手机短信和邮箱注册功能
本次提交完成了用户认证模块的注册扩展:
1. 新增阿里云短信和异步邮件发送工具类
2. 新增短信/邮箱相关配置类与环境变量支持
3. 添加短信验证码、待注册数据的Redis缓存工具方法
4. 扩展用户登录逻辑,支持用户名/邮箱/手机号多方式登录
5. 实现手机短信注册和邮箱验证注册完整流程
6. 更新权限初始化数据与系统配置项
7. 补充相关Pydantic请求响应模型
8. 新增依赖包并完善requirements.txt
2026-06-14 22:19:33 +08:00

81 lines
2.3 KiB
Python

import redis.asyncio as redis
from config import redis_settings
# 创建Redis连接池
redis_pool = redis.ConnectionPool.from_url(
redis_settings.url,
decode_responses=True
)
async def get_redis():
"""获取Redis连接"""
async with redis.Redis(connection_pool=redis_pool) as conn:
try:
yield conn
finally:
await conn.close()
async def set_token_in_redis(redis_conn, user_id: int, token: str, expire_seconds: int):
"""将令牌存储到Redis"""
key = f"user:token:{user_id}"
await redis_conn.set(key, token, ex=expire_seconds)
async def get_token_from_redis(redis_conn, user_id: int):
"""从Redis获取令牌"""
key = f"user:token:{user_id}"
return await redis_conn.get(key)
async def delete_token_from_redis(redis_conn, user_id: int):
"""从Redis删除令牌"""
key = f"user:token:{user_id}"
await redis_conn.delete(key)
async def check_token_in_redis(redis_conn, user_id: int, token: str):
"""检查令牌是否在Redis中且有效"""
stored_token = await get_token_from_redis(redis_conn, user_id)
return stored_token == token
# ========================================
# 注册相关:短信验证码
# ========================================
async def save_sms_code(redis_conn, phone: str, code: str, expire_seconds: int = 300):
"""存储短信验证码"""
key = f"sms_code:{phone}"
await redis_conn.set(key, code, ex=expire_seconds)
async def get_and_delete_sms_code(redis_conn, phone: str) -> str | None:
"""获取并删除短信验证码(一次性使用)"""
key = f"sms_code:{phone}"
code = await redis_conn.get(key)
if code:
await redis_conn.delete(key)
return code
# ========================================
# 注册相关:待注册数据(邮箱验证)
# ========================================
async def save_pending_registration(redis_conn, token_id: str, data: str, expire_seconds: int = 1800):
"""存储待注册数据"""
key = f"reg_pending:{token_id}"
await redis_conn.set(key, data, ex=expire_seconds)
async def get_and_delete_pending_registration(redis_conn, token_id: str) -> str | None:
"""获取并删除待注册数据(一次性使用)"""
key = f"reg_pending:{token_id}"
data = await redis_conn.get(key)
if data:
await redis_conn.delete(key)
return data