第12次07 :邮箱的验证
第1步:开启信箱SMTP服务,开启之后可以使用此邮箱给用户的邮箱发送验证邮件。
登录QQ邮箱—点击右上角“设置”—点击左下角“账号与安全”—点击左侧“安全设置”—找到“POP3/IMAP/SMTP/Exchange/CardDA服务"选项,按提示步骤开启SMTP服务,需要发送两个手机验证码。
第2步:在dev.py中设置邮件参数
# 指定邮件后端
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.qq.com' # 邮件主机
EMAIL_PORT = 465 # 邮件端口
EMAIL_USE_SSL = True
EMAIL_HOST_USER = '316620938@qq.com' # 授权的邮件,此外应为商城的官方邮箱
EMAIL_HOST_PASSWORD = 'wdggtnpzpaebbiea' # 上一步邮箱授权时生成的密码,而不是邮箱的注册登录密码
EMAIL_FROM = '小鱼商城<316620938@qq.com>' #
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
第3步:定义发送邮件的函数,在users应用下创建emails.py,并定义函数
import loggingfrom django.conf import settings
from django.core.mail import send_maillogger = logging.getLogger('django')def send_verification_email(to_email, verify_url):"""发送邮件"""subject = '小鱼商城邮箱验证'html_message = '<p>尊敬的用户您好!</p>' \'<p>感谢您使用小鱼商城。</p>' \'<p>您的邮箱为:%s 。请单击此链接验证您的邮箱:</p>' \'<p><a href="%s">%s<a></p>' % (to_email, verify_url, verify_url)try:send_mail(subject, '', settings.EMAIL_FROM, [to_email], html_message=html_message)except Exception as e:logger.error(e)
第4步:在EmailView中补充发送验证邮箱的功能
class EmailView(LoginRequiredJSONMixin, View):"""添加邮箱"""def put(self, request):"""实现添加邮箱逻辑"""# 接收参数 body, 类型是bytes类型json_str = request.body.decode()json_dict = json.loads(json_str)email = json_dict.get('email')# print(email)if not email: # 校验参数return HttpResponseForbidden('缺少email参数')if not re.match(r'^[a-z0-9][\w\\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):return HttpResponseForbidden('参数email有误')# 赋值email字段try:request.user.email = emailrequest.user.save()except Exception as e:logger.error(e)return JsonResponse({'code': RETCODE.DBERR, 'errmsg': '添加邮箱失败'})# 补充验证邮箱的功能verify_url = '邮箱验证链接'send_verification_email(to_email=email, verify_url=verify_url)# 响应添加邮箱结果return JsonResponse({'code': RETCODE.OK, 'errmsg': '添加邮箱成功'})
第5步:安装用户信息序列化的库
pip install itsdangerous==1.1.0
第6步:定义验证邮箱的链接部分的固定串和有效期,在dev.py中
# 邮箱验证链接的固定字符串
EMAIL_VERIFY_URL = 'http://127.0.0.1:8000/emails/verification/'
# 邮箱验证链接的有效期,24小时
VERIFY_EMAIL_TOKEN_EXPIRES = 60 * 60 * 24
第7步:在users应用下utils.py中定义生成邮箱验证url的函数和反序列化的函数。
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, BadDatadef check_verify_email_token(token):"""反序列化token:param token:序列化后的token:return:user"""serializer = Serializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)try:data = serializer.loads(token)except BadData:return Noneelse:user_id = data.get('user_id')email = data.get('email')try:user = User.objects.get(id=user_id, email=email)except User.DoesNotExist:return Noneelse:return userdef generate_verify_email_url(user):"""生成邮箱验证url"""serializer = Serializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)data = {'user_id': user.id, 'email': user.email}token = serializer.dumps(data).decode()verify_url = settings.EMAIL_VERIFY_URL + '?token=' + tokenreturn verify_url
在users应用下创建constants.py,用于定义常量
# 邮件验证链接有效期:一天
VERIFY_EMAIL_TOKEN_EXPIRES = 60 * 60 * 24# 用户地址上限
USER_ADDRESS_COUNTS_LIMIT = 20
# 显示我的订单数量
ORDERS_LIST_LIMIT = 5
第8步:在users应用views.py中使用generate_verify_email_url()
函数,将原来的字符串换在函数
# verify_url = '邮箱验证链接'
verify_url = generate_verify_email_url(request.user)
第9步:views.py中定义验证邮箱的类视图
class VerifyEmailView(View):"""验证邮箱"""def get(self, request):# 从请求中取到tokentoken = request.GET.get('token')if not token:return HttpResponseForbidden('缺少token')user = check_verify_email_token(token) # 从token中提取信息try:user.email_active = Trueuser.save()except Exception as e:logger.error(e)return HttpResponseForbidden('邮箱验证失败')return redirect(reverse('users:info'))
第10步:定义路由
path('emails/verification/', views.VerifyEmailView.as_view()),