当前位置: 首页>移动开发>正文

【Django开发】前后端分离美多商城项目第9篇:邮件与验证,学习目标:【附代码文档】

【Django开发】前后端分离美多商城项目第9篇:邮件与验证,学习目标:【附代码文档】,第1张

美多商城项目4.0文档完整教程(附代码资料)主要内容讲述:美多商城,项目准备1.B2B--企业对企业,2.C2C--个人对个人,3.B2C--企业对个人,4.C2B--个人对企业,5.O2O--线上到线下,6.F2C--工厂到个人。项目准备,配置1. 修改settings/dev.py 文件中的路径信息,2. INSTALLED_APPS,3. 数据库,4. Redis,5. 本地化语言与时区,6. 日志。用户部分,图片验证码。用户部分,使用Celery完成发送短信1. 判断用户名是否存在,2. 判断手机号是否存在:。用户部分,JWT起源,基于token的鉴权机制,JWT长什么样?,JWT的构成,总结,安装配置。用户部分,登录创建模型类,urllib使用说明。登录,登录回调处理创建模型类,urllib使用说明。登录,绑定用户身份接口创建模型类,urllib使用说明。邮件与验证,保存邮箱并发送验证邮件。收货地址,省市区地址查询。收货地址,使用缓存。商品部分,数据库表设计表结构,数据库模型类,1. 什么是FastDFS,2. 文件上传流程,3. 简易FastDFS构建。Docker使用,Docker简介1. 虚拟化,2. 什么是Docer,3. Docker组件,4 使用Docker做什么。Docker使用,安装与操作1. 在Ubuntu中安装Docker,2. 启动与停止,3. Docker镜像操作,4. Docker 容器操作,5. 将容器保存为镜像,6. 镜像备份与迁移。商品部分,FastDFS客户端与自定义文件存储系统1. FastDFS的Python客户端,2. 自定义Django文件存储系统,3. 在Django配置中设置自定义文件存储类,4. 添加image域名。商品部分,页面静态化。商品部分,商品详情页。商品部分,用户浏览历史记录1. 保存,2. 查看,获取商品列表数据。商品部分,商品搜索。购物车部分,购物车数据存储设计1. Redis保存已登录用户,2. Cookie保存未登录用户。购物车部分,查询购物车数据。购物车部分,登录合并购物车。订单部分,保存订单。支付,接入。Xadmin,用户权限控制1. 安装,2. 使用,1. 主从同步的定义,2. 主从同步的机制,3. 配置主从同步的基本步骤,4. 详细配置主从同步的方法。

全套笔记资料代码移步: 前往gitee仓库查看

感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~


全套教程部分目录:

【Django开发】前后端分离美多商城项目第9篇:邮件与验证,学习目标:【附代码文档】,第2张

【Django开发】前后端分离美多商城项目第9篇:邮件与验证,学习目标:【附代码文档】,第3张


部分文件图片:

【Django开发】前后端分离美多商城项目第9篇:邮件与验证,学习目标:【附代码文档】,第4张

邮件与验证

学习目标:
  • 使用Django发送邮件的方法
  • 邮件激活的机制
业务说明:

在用户中心页面中,我们允许用户设置邮箱

【Django开发】前后端分离美多商城项目第9篇:邮件与验证,学习目标:【附代码文档】,设置邮箱,第5张

当用户点击保存后,我们会向用户发送邮件以验证邮箱的有效性。

【Django开发】前后端分离美多商城项目第9篇:邮件与验证,学习目标:【附代码文档】,验证邮件,第6张

为了避免用户未收到验证邮箱,我们提供“重新发送验证邮件”按钮允许用户重新发送邮件。

【Django开发】前后端分离美多商城项目第9篇:邮件与验证,学习目标:【附代码文档】,重新发送验证邮件,第7张

邮箱验证成功,显示已验证。

【Django开发】前后端分离美多商城项目第9篇:邮件与验证,学习目标:【附代码文档】,邮箱已验证,第8张

技术说明:

在邮件中提供的激活链接地址,为了能区分是哪个用户在进行邮箱验证,需要在链接中包含用户和邮箱的识别信息,如user_id和email数据,但是基于安全性的考虑,不能将这两个数据直接暴露在邮件链接中,而是需要进行隐藏和签名处理(能够检测出是否修改过链接数据)。可以使用前面学过的itsdangerous对user_id和email数据进行处理,生成token作为链接的参数。

保存邮箱并发送验证邮件

后端接口设计:

请求方式:PUT /email/

请求参数: JSON 或 表单

参数 类型 是否必须 说明
email str Email邮箱

返回数据: JSON

返回值 类型 是否必须 说明
id int 用户id
email str Email邮箱

在users/serializers.py中新建序列化器,用户验证用户提交的邮箱信息。

class EmailSerializer(serializers.ModelSerializer):
    """
    邮箱序列化器
    """
    class Meta:
        model = User
        fields = ('id', 'email')
        extra_kwargs = {
            'email': {
                'required': True
            }
        }

    def update(self, instance, validated_data):
        instance.email = validated_data['email']
        instance.save()
        return instance

在users/views.py中创建新视图,用于保存用户的邮箱信息,注意需要用户登录通过认证后。

from rest_framework.permissions import IsAuthenticated

class EmailView(UpdateAPIView):
    """
    保存用户邮箱
    """
    permission_classes = [IsAuthenticated]
    serializer_class = serializers.EmailSerializer

    def get_object(self, *args, **kwargs):
        return self.request.user

设置路由信息

url(r'^emails/$', views.EmailView.as_view()),  # 设置邮箱

补充发送验证邮件

在保存邮箱的时候,需要向用户发送验证邮件,我们将发送邮件的工作放到celery中异步执行。

在celery*tasks目录中新建email目录和email/*_init**.py文件和email/tasks.py文件

email/tasks.py文件中是实现发送邮件的异步任务

from celery_tasks.main import celery_app
from django.core.mail import send_mail
from django.conf import settings


@celery_app.task(name='send_verify_email')
def send_verify_email(to_email, verify_url):
    """
    发送验证邮箱邮件
    :param to_email: 收件人邮箱
    :param verify_url: 验证链接
    :return: None
    """
    subject = "美多商城邮箱验证"
    html_message = '<p>尊敬的用户您好!</p>' \
                   '<p>感谢您使用美多商城。</p>' \
                   '<p>您的邮箱为:%s 。请点击此链接激活您的邮箱:</p>' \
                   '<p><a rel="nofollow" href="%s">%s<a></p>' % (to_email, verify_url, verify_url)
    send_mail(subject, "", settings.EMAIL_FROM, [to_email], html_message=html_message)
注意

在发送邮件的异步任务中,需要用到django的配置文件,所以我们需要修改celery的启动文件main.py,在其中指明celery可以读取的django配置文件,并且注册添加email的任务

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'])
在User模型类中定义生成验证邮箱链接的方法

邮箱的激活链接是用户点击时会访问的网址,我们让用户点击时进入到success_verify_email.html页面。

def generate_verify_email_url(self):
        """
        生成验证邮箱的url
        """
        serializer = TJWSSerializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)
        data = {'user_id': self.id, 'email': self.email}
        token = serializer.dumps(data).decode()
        verify_url = ' + token
        return verify_url
修改EmailSerializer序列化器的update方法,增加发送邮件
def update(self, instance, validated_data):
        email = validated_data['email']
        instance.email = email
        instance.save()

        # 生成验证链接
        verify_url = instance.generate_verify_email_url()
        # 发送验证邮件
        send_verify_email.delay(email, verify_url)
        return instance

前端

修改user_center_info.js文件,增加save_email方法

// 保存email
        save_email: function(){
            var re = /^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$/;
            if(re.test(this.email)) {
                this.email_error = false;
            } else {
                this.email_error = true;
                return;
            }
            axios.put(this.host + '/email/',
                { email: this.email },
                {
                    headers: {
                        'Authorization': 'JWT ' + this.token
                    },
                    responseType: 'json'
                })
                .then(response => {
                    this.set_email = false;
                    this.send_email_btn_disabled = true;
                    this.send_email_tip = '已发送验证邮件'
                })
                .catch(error => {
                    alert(error.data);
                });
        }

验证邮箱链接

当用户点击邮箱里的链接时,进入到success_verify_email.html页面。

在该页面中,我们将请求网址中用于验证的token发送给后端接口,由后端接口判断token的有效性,如果token有效,则修改邮箱的验证状态,并将处理结果返回给前端展示给用户。

后端接口设计:

请求方式:GET /emails/verification/?token=xxx

请求参数: 查询字符串参数

参数 类型 是否必须 说明
token str 用于验证邮箱的token

返回数据: JSON

返回值 类型 是否必须 说明
message str 验证处理结果

在users/views.py 中新建视图

  
  
# url(r'^emails/verification/$', views.VerifyEmailView.as_view()),
  
  
class VerifyEmailView(APIView):
    """
    邮箱验证
    """
    def get(self, request):
        # 获取token
        token = request.query_params.get('token')
        if not token:
            return Response({'message': '缺少token'}, status=status.HTTP_400_BAD_REQUEST)

        # 验证token
        user = User.check_verify_email_token(token)
        if user is None:
            return Response({'message': '链接信息无效'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            user.email_active = True
            user.save()
            return Response({'message': 'OK'})

在User模型类中定义验证token的方法

@staticmethod
    def check_verify_email_token(token):
        """
        检查验证邮件的token
        """
        serializer = TJWSSerializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)
        try:
            data = serializer.loads(token)
        except BadData:
            return None
        else:
            email = data.get('email')
            user_id = data.get('user_id')
            try:
                user = User.objects.get(id=user_id, email=email)
            except User.DoesNotExist:
                return None
            else:
                return user
前端

在front_end_pc目录中新建success_verify_email.html文件

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
<html xmlns=" xml:lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>美多商城-邮箱验证成功</title>
    <link rel="stylesheet" type="text/css" href="css/reset.css">
    <link rel="stylesheet" type="text/css" href="css/main.css">
    <script type="text/javascript" src="js/vue-2.5.16.js"></script>
    <script type="text/javascript" src="js/axios-0.18.0.min.js"></script>
    <script type="text/javascript" src="js/host.js"></script>
</head>
<body>
    <div class="find_header">
        <img src="images/logo.png">
        <span class="sub_page_name fl">|&nbsp;&nbsp;&nbsp;&nbsp;邮箱验证成功</span>
    </div>

    <div class="find_form" id="email_result">
        <div v-if="success" class="pass_change_finish">恭喜您,邮箱验证成功!<br/><a rel="nofollow" href="/index.html">返回主页</a></div>
        <div v-else class="pass_change_finish">链接已失效,验证失败,请重新验证!<br/><a rel="nofollow" href="/index.html">返回主页</a></div>
    </div>

    <div class="footer no-mp">
        <div class="foot_link">
            <a rel="nofollow" href="#">关于我们</a>
            <span>|</span>
            <a rel="nofollow" href="#">联系我们</a>
            <span>|</span>
            <a rel="nofollow" href="#">招聘人才</a>
            <span>|</span>
            <a rel="nofollow" href="#">友情链接</a>        
        </div>
        <p>CopyRight © 2016 北京美多商业股份有限公司 All Rights Reserved</p>
        <p>电话:010-****888    京ICP备*******8号</p>
    </div>
    <script>
        var vm = new Vue({
            el: '#email_result',
            data: {
                host,
                success: true
            },
            created: function(){
                axios.get(this.host+'/emails/verification/'+ document.location.search)
                    .then(response => {
                        this.success = true;
                    })
                    .catch(error => {
                        this.success = false;
                    });
            }
        });
    </script>    
</body>
</html>

收货地址

【Django开发】前后端分离美多商城项目第9篇:邮件与验证,学习目标:【附代码文档】,收货地址管理,第9张

在这个页面中,我们要实现用户地址的管理,主要的业务逻辑有:

  • 省市区地址的数据库建立与查询
  • 用户地址的增删改查处理
  • 设置默认地址
  • 设置地址标题

我们主要讲解省市区地址的三级联动和缓存,其余留给大家自己来实现。

学习目标:

  • 省市区三级联动
  • 在Django REST framework中使用缓存

未完待续, 同学们请等待下一期

全套笔记资料代码移步: 前往gitee仓库查看

感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~


https://www.xamrdz.com/mobile/4hx1925763.html

相关文章: