Django REST Framework 如何实现重新发送验证邮件功能
重发验证邮件功能实现方案
核心逻辑:重发接口无需用户登录,仅需传入注册邮箱,校验账号状态合法后生成新的激活token,复用原有邮件发送逻辑即可。
实现步骤
- 第一步:新增重发邮件请求的序列化器,完成入参校验
- 第二步:编写重发邮件API视图,处理核心业务逻辑
- 第三步:配置接口路由
1. 新增序列化器
from rest_framework import serializers from django.contrib.auth import get_user_model User = get_user_model() class ResendVerifyEmailSerializer(serializers.Serializer): email = serializers.EmailField(required=True) def validate_email(self, value): # 校验邮箱是否注册 try: user = User.objects.get(email=value) except User.DoesNotExist: raise serializers.ValidationError("该邮箱未注册账号") # 校验账号是否已经激活 if user.is_verified: raise serializers.ValidationError("该账号已完成激活,无需重复发送验证邮件") # 校验通过后存储用户对象,方便视图调用 self.user = user return value
2. 编写重发邮件视图
from rest_framework import status from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.throttling import AnonRateThrottle from rest_framework_simplejwt.tokens import RefreshToken from django.contrib.sites.shortcuts import get_current_site from django.urls import reverse # 导入你项目中原有发邮件的工具类 from .utils import Util class ResendVerifyEmail(APIView): serializer_class = ResendVerifyEmailSerializer # 增加匿名用户频率限制,防止恶意刷邮件接口,默认1分钟最多请求1次,可自定义配置 throttle_classes = [AnonRateThrottle] def post(self, request): serializer = self.serializer_class(data=request.data) serializer.is_valid(raise_exception=True) user = serializer.user # 复用原有激活链接生成逻辑 token = RefreshToken.for_user(user).access_token current_site = get_current_site(request).domain relativeLink = reverse('email-verify') absurl = 'http://'+current_site+relativeLink+"?token="+str(token) email_body = 'Hi '+ user.username + ',请点击下方链接验证你的邮箱:\n' + absurl data = { 'email_body':email_body, 'to_email':user.email, 'email_subject':'验证你的邮箱' } Util.send_email(data) return Response({'message':'验证邮件已重新发送,请查收'}, status=status.HTTP_200_OK)
3. 配置接口路由
在你的urls.py中添加对应路由即可:
path('resend-verify-email/', ResendVerifyEmail.as_view(), name='resend-verify-email'),
注意事项
- 可以把生成激活链接、发送邮件的逻辑抽成公共函数,避免注册接口和重发接口重复写相同代码
- 可以在settings.py中配置simplejwt的access token过期时间,比如设置激活链接1小时内有效:
from datetime import timedelta SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(hours=1), }
- 可选优化:原有激活接口的错误提示存在重复内容,可修改为
{'error':'激活链接已过期'}、{'error':'无效的激活令牌'},用户体验更友好。
内容的提问来源于stack exchange,提问作者Abinash Karki
相关产品推荐
相关产品推荐

