我想创建自己的电子邮件验证流程,其中用户输入其凭据并获取给定电子邮件的 OTP。当用户在 10 分钟的时限内输入正确的 OTP 时,它将注册该用户,并且他的凭据将永久存储在我的数据库中。 如何在 10 分钟的时间限制内临时存储凭证?
我正在考虑使用 django_pbkdf2_sha256 库哈希后存储凭证,并将其存储在我的 redis 缓存中 10 分钟。如果用户在此时间之后尝试输入,他们将需要新的 OTP 才能注册。这是一个好主意吗 ?
将敏感信息(例如用户凭据)存储在缓存中(即使是经过哈希处理的)也存在安全风险。以下是一些需要考虑的风险:
- 缓存安全漏洞: 如果你的缓存服务器遭到入侵,攻击者可能会访问缓存的数据,包括经过哈希处理的凭据。
- 未经授权的访问: 如果缓存配置不当,可能会导致未经授权的用户访问缓存的数据。
- 数据持久性: 缓存通常用于快速数据检索,并且可能无法保证数据的持久性。如果缓存服务器重启,数据可能会丢失。
更安全的方案是:
- 仅存储验证令牌:
- 生成一个唯一的、随机的、安全的验证令牌,并将其与用户的电子邮件地址和时间戳一起存储在数据库中。
- 将包含此令牌的链接发送到用户的电子邮件地址。
- 当用户点击链接时,检索与令牌关联的电子邮件地址,并检查时间戳是否在 10 分钟内。
-
如果有效,则允许用户设置密码并完成注册过程。
-
使用 Django 的内置密码重置机制:
- Django 提供了一个内置的密码重置系统,该系统可以轻松地适应电子邮件验证。
- 用户提交其电子邮件地址后,Django 会发送一封包含唯一链接的电子邮件。
- 该链接允许用户设置密码并完成注册。
改进你的方法:
- 不要存储经过哈希处理的密码: 即使使用强大的哈希函数,存储经过哈希处理的密码也存在风险。
-
使用安全的令牌生成器:
使用
secrets.token_urlsafe()
生成安全且唯一的令牌。 - 设置令牌的过期时间: 在数据库中存储令牌的创建时间,并在 10 分钟后使其过期。
示例代码(使用验证令牌):
from django.core.mail import send_mail
from django.utils.http import urlsafe_base64_encode
from django.utils.encoding import force_bytes
from django.template.loader import render_to_string
from django.contrib.auth.tokens import default_token_generator
from .models import User
def send_verification_email(user):
token = default_token_generator.make_token(user)
uid = urlsafe_base64_encode(force_bytes(user.pk))
verification_link = f'https://yourdomain.com/verify/{uid}/{token}'
subject = 'Verify Your Email Address'
message = render_to_string('accounts/verification_email.html', {
'verification_link': verification_link,
'user': user,
})
send_mail(subject, message, '[email protected]', [user.email])
def verify_email(request, uidb64, token):
try:
uid = urlsafe_base64_decode(uidb64).decode()
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user is not None and default_token_generator.check_token(user, token):
# 验证成功
user.is_active = True
user.save()
# 登录用户或重定向到成功页面
else:
# 无效的令牌
# 显示错误消息
请记住,安全是一个持续的过程,建议你始终使用最新的安全实践并定期审查你的代码以查找潜在的漏洞。
标签:python,django,authentication,email,email-verification From: 78846841