|
|
# 导入类型提示模块,用于定义函数参数和返回值的类型(增强代码可读性和类型检查)
|
|
|
import typing
|
|
|
# 导入timedelta,用于定义时间间隔(此处用于设置验证码有效期)
|
|
|
from datetime import timedelta
|
|
|
|
|
|
# 导入Django缓存模块,用于临时存储验证码(避免数据库频繁读写)
|
|
|
from django.core.cache import cache
|
|
|
# 导入Django翻译工具:gettext用于实时翻译字符串,gettext_lazy用于延迟翻译(适合定义常量时使用)
|
|
|
from django.utils.translation import gettext
|
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
|
|
# 导入项目自定义的发送邮件工具函数,用于实际发送验证码邮件
|
|
|
from djangoblog.utils import send_email
|
|
|
|
|
|
# 定义验证码的有效期:5分钟(全局常量,所有验证码共用此有效期)
|
|
|
_code_ttl = timedelta(minutes=5)
|
|
|
|
|
|
|
|
|
def send_verify_email(to_mail: str, code: str, subject: str = _("Verify Email")):
|
|
|
"""
|
|
|
发送密码重置验证邮件,将验证码通过邮件发送给指定邮箱
|
|
|
|
|
|
Args:
|
|
|
to_mail: 接收邮件的目标邮箱地址(字符串类型)
|
|
|
code: 生成的验证码(字符串类型,用于后续验证)
|
|
|
subject: 邮件主题,默认值为"Verify Email"(支持国际化,可根据语言设置自动翻译)
|
|
|
"""
|
|
|
# 构造邮件的HTML内容:包含验证码和有效期提示,使用国际化翻译,通过%(code)s格式化插入验证码
|
|
|
html_content = _(
|
|
|
"You are resetting the password, the verification code is:%(code)s, valid within 5 minutes, please keep it "
|
|
|
"properly") % {'code': code}
|
|
|
# 调用自定义的send_email函数发送邮件:参数为收件人列表、邮件主题、邮件内容
|
|
|
send_email([to_mail], subject, html_content)
|
|
|
|
|
|
|
|
|
def verify(email: str, code: str) -> typing.Optional[str]:
|
|
|
"""
|
|
|
验证用户输入的验证码是否有效(与缓存中存储的验证码对比)
|
|
|
|
|
|
Args:
|
|
|
email: 用户提交的邮箱地址(用于匹配缓存中对应的验证码)
|
|
|
code: 用户输入的验证码(需要验证的字符串)
|
|
|
|
|
|
Return:
|
|
|
验证失败时返回错误提示字符串(如"Verification code error"),验证成功时返回None
|
|
|
|
|
|
Note:
|
|
|
原代码注释说明:当前错误处理方式不合理,建议通过raise抛出异常替代返回错误字符串,
|
|
|
避免调用方需要额外处理返回的错误信息,使错误处理更符合Python规范
|
|
|
"""
|
|
|
# 从缓存中获取该邮箱对应的验证码(调用get_code函数)
|
|
|
cache_code = get_code(email)
|
|
|
# 对比用户输入的验证码与缓存中的验证码,不一致则返回错误提示
|
|
|
if cache_code != code:
|
|
|
return gettext("Verification code error")
|
|
|
|
|
|
|
|
|
def set_code(email: str, code: str):
|
|
|
"""
|
|
|
将邮箱与对应的验证码存储到Django缓存中,并设置过期时间(使用全局的_code_ttl)
|
|
|
|
|
|
Args:
|
|
|
email: 作为缓存键(key)的邮箱地址(确保每个邮箱的验证码唯一)
|
|
|
code: 作为缓存值(value)的验证码(需要存储的字符串)
|
|
|
"""
|
|
|
# 调用cache.set存储数据:key=email,value=code,timeout=_code_ttl.seconds(有效期转换为秒数)
|
|
|
cache.set(email, code, _code_ttl.seconds)
|
|
|
|
|
|
|
|
|
def get_code(email: str) -> typing.Optional[str]:
|
|
|
"""
|
|
|
根据邮箱地址从Django缓存中获取对应的验证码
|
|
|
|
|
|
Args:
|
|
|
email: 用于查询的缓存键(key),即目标邮箱地址
|
|
|
|
|
|
Return:
|
|
|
缓存中存在该邮箱对应的验证码时返回字符串类型的验证码,不存在或过期时返回None
|
|
|
"""
|
|
|
# 调用cache.get获取缓存值:key=email,不存在则返回None
|
|
|
return cache.get(email)
|