前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >邮箱验证

邮箱验证

作者头像
小闫同学啊
发布2019-07-18 11:41:58
4.4K0
发布2019-07-18 11:41:58
举报
文章被收录于专栏:小闫笔记小闫笔记

每日推荐

代码语言:javascript
复制
There is nothing so useless as doing efficiently  
that which should not be done at all.

今天分享的这句话,是管理学教授彼得·德鲁克说过的一句名言,大意是『没有什么比有效地做那些根本不需要做的事更无效的了』让我们不要浪费时间在那些无用的事上。

邮箱验证

需求

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

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

3.为了避免用户未收到验证邮件,我们提供『重新发送验证邮件』按钮,允许用户选择重新发送邮件。

4.当用户点击邮件中的连接之后,显示验证成功,然后再用户中心页面显示『已验证』按钮。

技术要点说明

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

1.使用Django发送邮件

Django中内置了邮件发送功能,被定义在django.core.mail模块中。发送邮件需要使用SMTP服务器,常用的免费服务器有:163、126、QQ,下面以163邮件为例。

a.注册163邮箱,登录后在顶部菜单栏『设置』下拉菜单中选择POP3/SMTP/IMAP选项。

b.在新页面中点击左侧『客户端授权密码』,在右侧页面勾选『开启』选项,弹出新窗口按提示进行操作,填写手机验证码。

c.填写授权码后提示开启成功。

d.在Django配置文件中,设置邮箱的配置信息

代码语言:javascript
复制
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.163.com'
EMAIL_PORT = 25
#发送邮件的邮箱
EMAIL_HOST_USER = 'xxxxx@163.com'
#在邮箱中设置的客户端授权密码
EMAIL_HOST_PASSWORD = 'xxxx'
#收件人看到的发件人
EMAIL_FROM = 'python<xxxxxx@163.com>'

e.使用Django提供的模块发送邮件

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字符串

例如:

代码语言:javascript
复制
msg='<a href="http://www.xxxx.cn/subject/pythonzly/index.shtml" target="_blank">点击激活</a>'
send_mail('注册激活','',settings.EMAIL_FROM, ['xxx@163.com'], html_message=msg)

2.保存邮箱并发送验证邮件

代码语言:javascript
复制
API: PUT /email/
参数:
    {
        "email":"邮箱"
    }
响应:
    {
        "id":"用户id",
        "email":"用户邮箱"
    }

业务逻辑

1.获取参数并进校校验(email必传,邮箱格式)。

2.设置登录用户的邮箱并给邮箱发送验证邮件。

3.返回应答,邮箱设置成功。

2.1详细步骤

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

代码语言:javascript
复制
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中创建新视图,用于保存用户的邮箱信息,注意需要用户登录通过认证后。

代码语言:javascript
复制
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

设置路由信息

代码语言:javascript
复制
url(r'^emails/$', views.EmailView.as_view()),  # 设置邮箱
2.2补充发送验证邮件

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

在celery_tasks目录中新建email包和并在包里面新建email/tasks.py文件

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

代码语言:javascript
复制
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,verfy_url):
    subject = "闫氏商城邮箱验证"
    html_message = '<p>尊敬的用户您好!</p>' \
                   '<p>你咋这么有眼光呢?欢迎使用我们闫氏商城。</p>' \
                   '<p>您的邮箱为:%s。请点击此链接(就是这个有蓝色下划线的东西)激活您的邮箱:</p>' \
                   '<p><a href="%s">%s<a></p>' %(to_email,verfy_url,verfy_url)
    send_mail(subject,"",settings.EMAIL_FROM,[to_email],html_message=html_message)
2.2.1注意

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

代码语言:javascript
复制
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'])
2.2.2在User模型类中定义生成验证邮箱链接的方法

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

代码语言:javascript
复制
class User(AbstrackUser):
    ...
    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 = 'http://www.meiduo.site:8080/success_verify_email.html?token=' + token
        return verify_url
2.2.3修改EmailSerializer序列化器的update方法,增加发送邮件
代码语言:javascript
复制
def update(self, instance, validated_data):
        # 设置登录用户的邮箱
        email = validated_data['email']
        instance.email = email
        instance.save()

        # TODO:并给邮箱发送验证邮件
        # 验证链接地址:http://api.meiduo.site:8000/success_verify_email.html?token=<加密用户信息>
        verify_url = instance.generate_verify_email_url()

        # 发出发送邮件的任务消息
        # send_mail()
        from celery_tasks.email.tasks import send_verify_email
        send_verify_email.delay(email,verify_url)

        return instance

3.验证邮箱连接

代码语言:javascript
复制
API: PUT /emails/verification/?token=xxx
参数:
    {
        "token":"用于验证邮箱的token"
    }
响应:
    {
        "message":"验证处理结果"
    }

业务逻辑

1.获取token(加密用户信息)并进行校验(token必传,token是否有效)。

2.设置用户的邮箱验证标记True。

3.返回应答,邮箱验证成功。

3.1详细步骤

在users/views.py 中新建视图

代码语言:javascript
复制
# PUT /emails/verification/?token=<加密信息>
class EmailVerifyView(APIView):
    def put(self,request):
        """
        用户邮箱验证
        1.获取token(加密用户信息)并进行校验(token必传,token是否有效)
        2.设置用户的邮箱验证标记True
        3.返回应答,邮箱验证成功
        """
        # 1.获取token(加密用户信息)并进行校验(token必传,token是否有效)
        token = request.query_params.get('token')

        if token is None:
            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':'无效的token数据'},status=status.HTTP_400_BAD_REQUEST)

        # 2.设置用户的邮箱验证标记True
        user.email_active = True
        user.save()

        # 3.返回应答,邮箱验证成功
        return Response({'message':'OK'})

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

代码语言:javascript
复制
class User(AbstrackUser):
    ...
    @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

优质文章推荐:

公众号使用指南

redis操作命令总结

前端中那些让你头疼的英文单词

Flask框架重点知识总结回顾

项目重点知识点详解

难点理解&面试题问答

flask框架中的一些常见问题

团队开发注意事项

浅谈密码加密

Django框架中的英文单词

Django中数据库的相关操作

DRF框架中的英文单词

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈技术精选 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 每日推荐
  • 邮箱验证
    • 1.使用Django发送邮件
      • 2.保存邮箱并发送验证邮件
        • 3.验证邮箱连接
        相关产品与服务
        文件存储
        文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档