python学习之美多商城(九):用户模块--用户中心个人信息、邮件验证、celery异步实现发送邮件

一、用户中心个人信息:

前端访问个人信息页面时,需要向后端请求个人信息。
在本页面中要显示用户的Email邮箱信息,而对于邮箱信息我们要实现对于邮箱的验证功能,并在本页面中显示邮箱是否已验证,如下所示,
在这里插入图片描述

1.修改User模型:

由上图可知,我们需要在User模型类中增加一个邮箱是否验证的字段:

class User(AbstractUser):
	"""
	用户信息
	"""
	mobile = models.CharField(max_length=11, unique=True, verbose_name="手机号")
    email_active = models.BooleanField(default=False, verbose_name='邮箱验证状态')

2.后端接口设计:

请求方式: GET /user/
请求参数: token(headers中)
返回数据: JSON

返回值类型是否必须说明
idint用户id
usernamestr用户名
mobilestr手机号
emailstremail邮箱
email_activebool邮箱是否通过验证

3.后端代码实现:

定义一个序列化器,用来序列化返回用户数据

# users/serializers.py
class UserDetailSerializer(serializers.ModelSerializer):
    """
    用户详细信息序列化器
    """
    class Meta:
        model = User
        fields = ('id', 'username', 'mobile', 'email', 'email_active')
# user/views.py
# url(r'^user/$', views.UserDetailView.as_view()),
class UserDetailView(RetrieveAPIView):
    """用户详情"""
    serializer_class = UserDetailSerializer
    permission_classes = [IsAuthenticated]  # 用户验证

    def get_object(self):
        """
        重写get_object,不使用pk值返回user
        :return: 
        """
        return self.request.user

注意:访问视图必须要求用户已通过认证(即登录之后)


二、邮件与验证:

1.学习目标:

  • 使用Django发送邮件的方法
  • 邮件激活的机制

2.业务说明:

在用户中心页面中,允许用户设置邮箱
当用户点击保存后,我们会向用户发送邮件以验证邮箱的有效性。

(邮箱验证图片)

为了避免用户未收到验证邮箱,我们提供“重新发送验证邮件”按钮允许用户重新发送邮件。
在这里插入图片描述
邮箱验证成功,显示已验证
(显示已验证图片)

3.技术说明:

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

4.、Django发送邮件的方法:

4.1 使用Django发送邮件:

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

1) 注册163邮箱并登陆后设置:

在这里插入图片描述

2)在新页面中点击"客户端授权密码",勾选"开启",弹出新窗口填写手机验证码:

在这里插入图片描述

3)填写授权码:

在这里插入图片描述

4)提示开启成功:

在这里插入图片描述

5)在Djnago配置文件中,设置邮箱的配置信息:
# Django的邮箱配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.163.com'
EMAIL_PORT = 25
#发送邮件的邮箱
EMAIL_HOST_USER = '135****6183@163.com'
#在邮箱中设置的客户端授权密码
EMAIL_HOST_PASSWORD = 'test001'
#收件人看到的发件人
EMAIL_FROM = 'meiduo<135****6183@163.com>'
6)使用Djnago提供的模块发送邮件:

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

例如:

msg='<a href="http://www.itcast.cn/subject/pythonzly/index.shtml" target="_blank">点击激活</a>'
send_mail('注册激活','',settings.EMAIL_FROM, ['135****6183@163.com@163.com'], html_message=msg)

5. 保存邮件并发送验证邮件:

5.1 保存邮箱地址后端接口设计:

请求方式: PUT /email/
请求参数: JSON或表单

参数类型是否必须说明
emailstremail邮箱

返回数据: JSON

返回值类型是否必须说明
idint用户ID
emailstr用户邮箱

5.2 保存地址后端代码实现:

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

# user/serializers.py
class EmailSerializer(serializers.ModelSerializer):
    """保存邮箱序列化器"""
    class Meta:
        model = User
        fields = ('id', 'email')
        extra_kwargs = {
            'email':{
                'required':True # 是否必传
            }
        }

    def update(self, instance, validated_data):
        """
        更新邮箱到用户字段
        :param instance:
        :param validated_data:
        :return:
        """
        instance.email = validated_data["email"]
        instance.save()
        return instance

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

# /user/views.py
class EmailView(UpdateAPIView):
    """
    保存用户邮箱
    """
    permission_classes = [IsAuthenticated]  # 验证用户登录
    serializer_class = EmailSerializer

    def get_object(self, *args, **kwargs):
        """
        重写get_object方法,获取当前用户对象
        update()中需要get_object获
        :param args:
        :param kwargs:
        :return:
        """
        return self.request.user

设置路由信息:

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

5.3 实现发送邮件(celery异步实现)

在保存邮箱的时候,需要向用户发送验证邮件,我们将发送邮件的工作放到celery中异步执行。
在celert_tasks目录中新建email目录、email/init.py和email/asks.py文件
在email/tasks.py文件中是实现发送邮件的异步任务:

# -*-coding:utf-8-*-
# celert_tasks/email/tasks.py
from celery_tasks.main import app
from django.core.mail import send_mail
from django.conf import settings

@app.task(name='send_verify_email')
def send_verify_email(to_email, verify_url):
    """
    发送验证邮箱的邮件
    :param to_mail: 收件人邮箱
    :param verify_url: 验证链接
    :return: 
    """
    subject = "美多商城邮箱验证"
    html_message = '<p>尊敬的用户您好!</p>' \
                   '<p>感谢您使用美多商城。</p>' \
                   '<p>您的邮箱为:%s 。请点击此链接激活您的邮箱:</p>' \
                   '<p><a 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的任务

# celert_tasks/main.py
...

# 自动注册celery任务
app.autodiscover_tasks([
        'celery_tasks.sms',
        'celery_tasks.tasks',
                        ])

在User子应用的序列化器类中定义生成验证邮箱链接的方法
邮箱的激活链接是用户点击时会访问的网址,我们让用户点击时进入到success_verify_email.html页面。

# apps/users/serializers/EmailSerializer

def generate_verify_email_url(self,instance):
        """
        生成验证邮箱的url
        :return:
        """
        tjs = TJS(settings.SECRET_KEY, 300)
        token = tjs.dumps({"name":instance.username}).decode()
        verify_url = 'http://www.meiduo.site:8080/success_verify_email.html?token=' + token
        return verify_url

修改EmailSerializer序列化器的update方法,增加发送邮件

# apps/users/serializers/EmailSerializer
def update(self, instance, validated_data):
        """
        更新邮箱到用户字段
        :param instance:
        :param validated_data:
        :return:
        """
        instance.email = validated_data["email"]
        instance.save()
        # 生成验证url
        verify_url = self.generate_verify_email_url(instance)
        email = instance.email
        # 异步发送邮件
        send_verify_email.delay(email, verify_url)
        return instance

6.验证邮箱链接:

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

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

6.1 验证邮箱后端接口设计:

请求方式: GET emails/verification/?token= ****
请求参数: 查询字符串

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

返回数据: JSON

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

6.2 后端代码实现:

在users/views.py中新建视图:

# apps/users/views.py
class VerifyEmailView(APIView):
    """验证邮箱"""
    def get(self, request):
        """
        验证邮箱,将用户数据中的邮箱状态置为真
        :param request:
        :return:
        """
        # 获取token
        token = request.query_params.get('token')
        tjs = TJS(settings.SECRET_KEY, 300)
        try:
            data = tjs.loads(token)
        except:
            return Response({"errors":"token无效"}, status=status.HTTP_400_BAD_REQUEST)

        # 查找用户
        username = data.get("username")
        print("username:{}".format(username))
        try:
            user = User.objects.get(username=username)
        except:
            return Response({"errors":"用户不存在"},status=status.HTTP_400_BAD_REQUEST)

        # 更改用户邮箱验证状态
        user.email_active = True
        user.save()
        return Response({"message":True})

配置路由:

url(r"^emails/verification/$",views.VerifyEmailView.as_view()),
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浅弋、璃鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值