Django项目(四)实现用户中心和邮件验证

一.用户中心

由于要判断邮箱是否激活,所以需要添加一个email_active字段在User模型类中

 email_active = models.BooleanField(default=False, verbose_name='邮箱验证状态')

进行数据库迁移

python manage.py makemigrations
python manage.py migrate

后端接口设计:

请求方式: GET/users/infos/

返回数据:

返回值 类型 是否必须 说明
id int 用户id
username str 用户名
mobile str 手机号
email str email邮箱
email_active bool 邮箱是否通过验证

 在users/serializers.py中创建序列化器

class UserDetailSerializer(serializers.ModelSerializer):
    """
    用户详细信息序列化器
    """
    class Meta:
        model = User
        fields = ('id', 'username', 'mobile', 'email', 'email_active')

新建视图

class UserDetailView(RetrieveAPIView):
    """
    获取登录用户的信息
    GET /users/
    既然是登录用户,我们就要用到权限管理
    在类视图对象中也保存了请求对象request
    request对象的user属性是通过认证检验之后的请求用户对象
    """
    permission_classes = [IsAuthenticated]

    serializer_class = UserDetailSerializer

    def get_object(self):
        return self.request.user

 添加路由:

urlpatterns = [
   ...
    #GET /users/infos/
    url(r'^infos/$',views.UserDetailView.as_view(),name='detail'),

]

 修改前端代码HTML和JS

二.邮箱验证

1.Django中内置了邮件发送功能

被定义在django.core.mail模块中。发送邮件需要使用SMTP服务器,这里我们使用163邮箱为例

配置好获取配置信息

# 邮箱配置信息
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.163.com'
EMAIL_PORT = 25
#发送邮件的邮箱
EMAIL_HOST_USER = '[email protected]'
#在邮箱中设置的客户端授权密码
EMAIL_HOST_PASSWORD = 'dashabi222'
#收件人看到的发件人
EMAIL_FROM = '美多商城<[email protected]>'

将配置信息添加到setting中

django.core.mail模块提供了send_mail来发送邮件

2.在user模型类中添加email_active字段

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

    class Meta:
        db_table = 'tb_users'
        verbose_name = '用户'
        verbose_name_plural = verbose_name

3.数据库迁移:python manage.py makemagrations

                      python manage.py migrate

4.点击保存按钮

         1.邮箱字段保存到数据库

          2.保存后邮箱向用户绑定的邮箱发送验证链接

后端接口设计:

请求方式:PUT/users/emails/

请求参数:

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

返回数据:

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

创建一个新视图用来处理邮件 

1.只有登录的用户才能保存邮件,添加用户权限

2.添加序列化器

3.由于直接继承的UpdateAPIView,没有传递PK值,所以,也需要重写get_object方法

class EmailView(UpdateAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = EmailSerializer

    def get_object(self):
        return self.request.user

序列化器:

class EmailSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id','email']
        extra_kwargs = {
            'email': {
                'required': True
            }
        }

    def update(self, instance, validated_data):
        email = validated_data.get('email')
        instance.email = email
        instance.save()
        # 在这里发送激活邮件
        url = instance.generic_verify_url()
        from celery_tasks.email.tasks import send_verify_mail
        send_verify_mail.delay(email,url)
        return instance

重写update方法,在将邮件地址保存到数据库后,发送激活邮件

激活邮件需要一定的时间,我们要功能放在celery中来实现

在celery文件夹中创建email文件夹,在tasks.py文件中增加任务

from ..main import app
from django.core.mail import send_mail
from mall import settings


@app.task(name='send_verify_mail')
def send_verify_mail(email, url):
    # subject, message, from_email, recipient_list,html_message=None
    subject = '美多商城激活邮件'
    message = ''
    from_email = settings.EMAIL_FROM  # 发件人
    recipient_list = [email]  # 收件人列表
    # 可以传递 html代码
    # 我们需要生成一个url,这个url中的token需要包含用户的id信息(id需要被处理)
    html_message = '<p>尊敬的用户您好!</p>' \
                   '<p>感谢您使用美多商城。</p>' \
                   '<p>您的邮箱为:%s 。请点击此链接激活您的邮箱:</p>' \
                   '<p><a href="%s">%s<a></p>' % (email, url, url)
    send_mail(subject, message, from_email, recipient_list, html_message=html_message)

收件人列表添加在这里recipient_list = [email]  # 收件人列表

终端使用celery命令:

celery -A celery_tasks.main worker -l info

model类里写了两个方法

此时,在收件人列表中的邮箱可以收到我们发送过去的激活邮件

def generic_verify_url(self):
        serializer = Serializer(settings.SECRET_KEY, 3600)
        token = serializer.dumps({'id': self.id, 'email': self.email})
        return 'http://www.meiduo.site:8080/success_verify_email.html?token=' + token.decode()

    @staticmethod
    def check_verify_email_token(token):
        serializer = Serializer(settings.SECRET_KEY, 3600)
        try:
            result = serializer.loads(token)
        except BadData:
            return None
        else:
            user_id = result.get('id')
            email = result.get('email')
            try:
                user = User.objects.get(id=user_id, email=email)
            except User.DoesNotExist:
                user = None
            else:
                return user

前面在创建URL时有调用这个方法将用户id和邮箱加密成token值发送给需要激活的邮箱

5.接下来需要实现激活邮箱功能,点击激活邮件中的URL

后端接口设计:

请求方式:GET /users/emails/verification/

请求参数:

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

返回数据:

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

1.创建一个新的视图来处理这个功能

取得token值,对token值进行解密,得到user_id和email,通过id得到user对象,将email_active字段的值改成true

class VerificationEmailView(APIView):
    """
    验证激活邮箱
    GET /users/emails/verification/?token=xxxx

    思路:
    获取token,并判断
    获取 token中的id
    查询用户,并判断是否存在
    修改状态
    返回响应
    """
    def get(self,request):
        token = request.query_params.get('token')
        if not token:
            return Response({'message':'缺少token'},status=status.HTTP_400_BAD_REQUEST)
        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'})

这里用到了前面模型类中的check_verify_email_token用来解密,得到user_id和email

修改前端代码就能实现邮件的激活和绑定了

功能实现前:

功能实现后

猜你喜欢

转载自blog.csdn.net/Spencer_q/article/details/82055466
今日推荐