二、添加和验证邮箱

2.1 添加邮箱后端逻辑

1. 添加邮箱接口设计和定义

1.请求方式

选项 方案
请求方法 PUT
请求地址 /emails/
    #  添加邮箱url(r'^emails/$', views.EmailView.as_view()),

2.请求参数

参数名 类型 是否必传 说明
email string 邮箱

3.响应结果:JSON

字段 说明
code 状态码
errmsg 错误信息

2. 添加邮箱后端逻辑实现

class EmailView(View):"""添加邮箱"""def put(self, request):"""实现添加邮箱逻辑"""# 接收参数json_dict = json.loads(request.body.decode())email = json_dict.get('email')# 校验参数if not email:return http.HttpResponseForbidden('缺少email参数')if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):return http.HttpResponseForbidden('参数email有误')# 赋值email字段try:request.user.email = emailrequest.user.save()except Exception as e:logger.error(e)return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '添加邮箱失败'})# 响应添加邮箱结果return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '添加邮箱成功'})

3. 判断用户是否登录并返回JSON

重要提示:

  • 只有用户登录时才能让其绑定邮箱。
  • 此时前后端交互的数据类型是JSON,所以需要判断用户是否登录并返回JSON给用户。

方案一:

  • 使用Django用户认证系统提供的is_authenticated()
class EmailView(View):"""添加邮箱"""def put(self, request):"""实现添加邮箱逻辑"""# 判断用户是否登录并返回JSONif not request.user.is_authenticated():return http.JsonResponse({'code': RETCODE.SESSIONERR, 'errmsg': '用户未登录'})pass

方案二:

  • 自定义返回JSON的login_required装饰器
  • meiduo_mall.utils.views.py
def login_required_json(view_func):"""判断用户是否登录的装饰器,并返回json:param view_func: 被装饰的视图函数:return: json、view_func"""# 恢复view_func的名字和文档@wraps(view_func)def wrapper(request, *args, **kwargs):# 如果用户未登录,返回json数据if not request.user.is_authenticated():return http.JsonResponse({'code': RETCODE.SESSIONERR, 'errmsg': '用户未登录'})else:# 如果用户登录,进入到view_func中return view_func(request, *args, **kwargs)return wrapperclass LoginRequiredJSONMixin(object):"""验证用户是否登陆并返回json的扩展类"""@classmethoddef as_view(cls, **initkwargs):view = super().as_view(**initkwargs)return login_required_json(view)

LoginRequiredJSONMixin的使用

class EmailView(LoginRequiredJSONMixin, View):"""添加邮箱"""def put(self, request):"""实现添加邮箱逻辑"""# 判断用户是否登录并返回JSONpass

2.2 Django发送邮件的配置

1. Django发送邮件流程分析

send_mall()方法介绍

  • 位置:

    • django.core.mail模块提供了send_mail()来发送邮件。
  • 方法参数:
    • send_mail(subject, message, from_email, recipient_list, html_message=None)
subject 邮件标题
message 普通邮件正文,普通字符串
from_email 发件人
recipient_list 收件人列表
html_message 多媒体邮件正文,可以是html字符串

2. 准备发邮件服务器

1.点击进入《设置》界面

2.点击进入《客户端授权密码》界面

3.开启《授权码》,并完成验证短信

4.填写《授权码》

5.完成《授权码》设置

6.配置邮件服务器

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # 指定邮件后端
EMAIL_HOST = 'smtp.163.com' # 发邮件主机,SMTP服务器
EMAIL_PORT = 25 # 发邮件端口
EMAIL_HOST_USER = 'XXXXXXX@163.com' # 授权的邮箱
EMAIL_HOST_PASSWORD = 'XXXXXXX' # 邮箱授权时获得的密码,非注册登录密码
EMAIL_FROM = '美多商城<XXXXXX@163.com>' # 发件人抬头

2.3 发送邮箱验证邮件

重要提示:

  • 发送邮箱验证邮件是耗时的操作,不能阻塞美多商城的响应,所以需要异步发送邮件
  • 我们继续使用Celery实现异步任务。

1. 定义和调用发送邮件异步任务

1.定义发送邮件任务

tasks.py

from django.conf import settings
from django.core.mail import send_mail
from celery_tasks.main import celery_app
import logging#  创建日志输出器
logger = logging.getLogger('django')
'''
bind:保证task对象会作为第一个参数自动传入
name:异步任务别名
retry_backoff:异常自动重试的时间间隔
max_retries:异常自动重试次数的上限
'''@celery_app.task(bind=True, name='send_verify_email', retry_backoff=3)
def send_verify_email(self, to_email, verify_url):"""发送验证邮箱邮件:param to_email: 收件人邮箱:param verify_url: 验证链接:return: None"""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)# 有异常自动重试三次raise self.retry(exc=e, max_retries=3)

2.注册发邮件的任务:main.py

  • 在发送邮件的异步任务中,我们用到了Django的配置文件。
  • 所以我们需要修改celery的启动文件main.py。
  • 在其中指明celery可以读取的Django配置文件。
  • 最后记得注册新添加的email的任务
#  启动celery文件
from celery import Celery# # 为celery使用django配置文件进行设置
# import os
# if not os.getenv('DJANGO_SETTINGS_MODULE'):
#     os.environ['DJANGO_SETTINGS_MODULE'] = 'meiduo_mall.settings.dev'#  创建celery实例
celery_app = Celery('meiduo')  # 参数可写可不写,没有多大意义
#  加载celery配置
celery_app.config_from_object('celery_tasks.config')#  自动注册celery任务
celery_app.autodiscover_tasks(['celery_tasks.sms', 'celery_tasks.email'])  # 就写任务包所在的位置

3.调用发送邮件异步任务

from celery_tasks.email.tasks import send_verify_email# 赋值email字段
try:request.user.email = emailrequest.user.save()
except Exception as e:logger.error(e)return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '添加邮箱失败'})# 异步发送验证邮件
verify_url = '邮件验证链接'
send_verify_email.delay(email, verify_url)# 响应添加邮箱结果
return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '添加邮箱成功'})

4.启动Celery   【在celery_tasks目录下执行】

$ celery -A celery_tasks.main worker -l info

在windows10上面运行celery4.x代码时可能会报错。

先安装一个`eventlet

pip install eventlet

然后启动worker的时候加一个参数,如下:

$ celery -A celery_tasks.main worker -l info -P eventlet

然后就可以正常的调用了。

2. 生成邮箱验证链接

1.定义生成邮箱验证链接方法

utils.py

from django.conf import settings
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from . import constantsdef generate_verify_email_url(user):"""生成邮箱验证链接:param user: 当前登录用户:return: verify_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

2.配置相关参数

# 邮箱验证链接
EMAIL_VERIFY_URL = 'http://www.meiduo.site:8000/emails/verification/'

3.使用邮箱验证链接

from .utils import generate_verify_email_urlverify_url = generate_verify_email_url(request.user)
send_verify_email.delay(email, verify_url)

2.4 验证邮箱后端逻辑

1. 验证邮箱接口设计和定义

1.请求方式

选项 方案
请求方法 GET
请求地址 /emails/verification/
#  验证邮箱url(r'^emails/verification/$', views.VerifyEmailView.as_view()),

2.请求参数:查询参数

参数名 类型 是否必传 说明
token string 邮箱激活链接

3.响应结果:HTML

字段 说明
邮箱验证失败 响应错误提示
邮箱验证成功 重定向到用户中心

2. 验证链接提取用户信息

utils.py

from itsdangerous import BadDatadef check_verify_email_token(token):"""验证token并提取user:param token: 用户信息签名后的结果:return: user, None"""#  序列化对象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 user

3. 验证邮箱后端逻辑实现

验证邮箱的核心:就是将用户的email_active字段设置为True

from .utils import check_verify_email_tokenclass VerifyEmailView(View):"""验证邮箱"""def get(self, request):"""实现邮箱验证逻辑"""# 接收参数token = request.GET.get('token')# 校验参数:判断token是否为空和过期,提取userif not token:return http.HttpResponseBadRequest('缺少token')user = check_verify_email_token(token)if not user:return http.HttpResponseForbidden('无效的token')# 修改email_active的值为Truetry:user.email_active = Trueuser.save()except Exception as e:logger.error(e)return http.HttpResponseServerError('激活邮件失败')# 返回邮箱验证结果return redirect(reverse('users:info'))

【加入在虚拟机中执行程序代码服务

若想在Windows下访问邮件验证,需要在虚拟机中把默认的ip改为0.0.0.0,即runserver 0.0.0.0:8000

在Windows下的hosts文件下加入:192.168.88.132  www.meiduo.site】

美多商城之用户中心(添加和验证邮箱)相关推荐

  1. Python_美多商城(用户中心)_5

    用户基本信息 用户基本信息逻辑分析 1. 用户基本信息逻辑分析 以下是要实现的后端逻辑 用户模型补充email_active字段 查询并渲染用户基本信息 添加邮箱 发送邮箱验证邮件 验证邮箱 提示: ...

  2. 美多商城之用户中心(用户基本信息)

    一.用户基本信息 1.1用户基本信息逻辑分析 1. 用户基本信息逻辑分析 以下是要实现的后端逻辑 用户模型补充email_active字段 查询并渲染用户基本信息 添加邮箱 发送邮箱验证邮件 验证邮箱 ...

  3. 美多商城之用户中心(收货地址3)

    三.收货地址 3.4 修改地址前后端逻辑 1. 修改地址接口设计和定义 1.请求方式 选项 方案 请求方法 PUT 请求地址 /addresses/(?P<address_id>\d+)/ ...

  4. 美多商城之用户中心(收货地址2)

    三.收货地址 3.2 新增地址前后端逻辑 1. 定义用户地址模型类 1.用户地址模型类 from meiduo_mall.utils.models import BaseModelclass Addr ...

  5. 美多商城之用户中心(修改密码)

    修改密码 1. 修改密码后端逻辑 提示: 修改密码前需要校验原始密码是否正确,以校验修改密码的用户身份. 如果原始密码正确,再将新的密码赋值给用户. class ChangePasswordView( ...

  6. 美多商城之用户中心(收货地址1)

    三.收货地址 用户地址的主要业务逻辑有: 展示省市区数据 用户地址的增删改查处理 设置默认地址 设置地址标题 3.1 省市区三级联动 1. 展示收货地址界面 提示: 省市区数据是在收货地址界面展示的, ...

  7. Django项目实战——7—(openid是否绑定用户的处理、用户基本信息渲染、添加和验证邮箱)

    1.openid是否绑定用户的处理 判断openid是否绑定过用户 使用openid查询该QQ用户是否在商城中绑定过用户. try:oauth_user = OAuthQQUser.objects.g ...

  8. 美多商城之用户登录(账号登录)

    一.账号登录 1.1用户名登录 1. 用户名登录逻辑分析 2. 用户名登录接口设计   [仍在user子项目中] 1.请求方式 选项 方案 请求方法 POST 请求地址 /login/ urls.py ...

  9. 美多商城之用户登录(QQ登录)

    二.QQ登录 2.1 QQ登录开发文档 QQ登录:即我们所说的第三方登录,是指用户可以不在本项目中输入密码,而直接通过第三方的验证,成功登录本项目. 1. QQ互联开发者申请步骤 若想实现QQ登录,需 ...

最新文章

  1. 协程在Socket上的应用
  2. 1039: 二哥的困惑 Ⅱ
  3. 【EntityFramework 6.1.3】个人理解与问题记录
  4. java 获取服务器网络名_java-siger java使用siger 获取服务器硬件信息(CPU 内存 网络 io等) - 下载 - 搜珍网...
  5. 如果删除github上项目的文件
  6. Python print 函数- Python零基础入门教程
  7. 解决placeholder样式设置无效问题,更改placeholder默认样式颜色
  8. cv_bridge 调用ros自带的opencv版本的解决
  9. 下载android平台源码
  10. OpenSSH学习笔记(安装配置openssh-4.6p1)[zz]
  11. vcs与quartus联合仿真
  12. 5G牌照发放3周年:为啥现在5G不火了?
  13. 食品机械怎么找客户,如何转型
  14. 什么是遥控灯开关:工作及其应用解析
  15. 基于Go语言Beego+Layui的OA办公系统
  16. 2020-09-25
  17. DeprecationWarning: Seeding based on hashing is deprecated since Python 3.9
  18. Linux环境中安装zookeeper
  19. android wifi精灵,全能WiFi精灵
  20. python1到100奇数相加_Python:从inpu将奇数相加

热门文章

  1. Java 开发技巧详细知识体系总结
  2. 对网络骚扰和霸凌说不!神经网络可以做得更好
  3. 嵌入式开发「坑」太多?MathWorks 高级工程师教你 debug
  4. 实战:人脸识别的Arcface实现 | CSDN博文精选
  5. NLP学习思维导图,非常的全面和清晰
  6. 百炼智百炼智能获5000万元Pre-A轮融资,深耕智能获客赛道
  7. 哈工大成立人工智能研究院,NLP全国前三
  8. 高逼格的 SQL 写法:行行比较,别问为什么,问就是逼格高。。
  9. 必须了解的MySQL三大日志:binlog、redo log和undo log
  10. Thread.sleep(0) 有什么用?