drf组件之jwt认证

drf组件之jwt认证模块

1、认证规则

全称:json web token 解释:加密字符串的原始数据是json,后台产生,经过web传输给前台存储 格式:三段式 - 头.载荷.签名 - 头和载荷用的是base64可逆加密,签名用md5不可逆加密 内容: 头(基础信息,也能够为空):加密方式、公司信息、项目组信息、... 载荷(核心信息):用户信息、过时时间、... 签名(安全保障):头加密结果+载荷加密结果+服务器秘钥 的md5加密结果html

认证规则: 后台必定要保障 服务器秘钥 的安全性(它是jwt的惟一安全保障) 后台签发token(login接口 ) -> 前台存储 -> 发送须要认证的请求带着token -> 后台校验获得合法的用户 -> 权限管理前端

为何要有jwt认证: 1)服务器压力小, 后台不须要存储token,只须要存储签发与校验token的算法,效率远远大于后台存储和取出token完成校验 2) jwt算法认证,更适合服务器集群部署python

2、认证模块

安装:pip install djangorestframework-jwt 模块包:rest_framework_jwtweb

采用drf-jwt框架,后期任务只须要书写登陆 为何要重写登陆:drf-jwt只完成了帐号密码登陆,咱们还须要手机登陆,邮箱登陆 为何不须要重写认证类:由于认证规则已经完成且固定不变,变得只有认证字符串的前缀,前缀能够在配置文件中配置算法

3、JWT使用

jwt配置;django

在settings.py文件中配置,若是不配置,默认走jwt默认的json

jwt插件的三个接口:api

在urls.py中配置安全

在postman中测试一下签发token服务器

注意:上面三个接口都是发送POST请求

4、利用JWT实现多方式登陆

注:APIResponse 为自定义Response对象

# views.py
from rest_framework.views import APIView
from . import models,serializers
from utils.response import APIResponse

class LoginAPIView(APIView):
    # 登陆接口应该禁用全部的认证和、权限,由于无论是谁都应该能进来
    authentication_classes = []
    permission_classes = []
    def post(self, request, *args, **kwargs):
        # 将数据传到序列化组件进行校验
        user_ser = serializers.LoginSerializer(data=request.data)
        user_ser.is_valid(raise_exception=True)

        return APIResponse(msg='login success', data={
            'username': user_ser.user.username,
            'token': user_ser.token
        })

注意:

经过user对象生成payload载荷 payload = jwt_payload_handler(user)

经过payload签发token token = jwt_encode_handler(payload)

# serializer.py
from rest_framework.serializers import ModelSerializer, CharField, ValidationError, SerializerMethodField
from . import models
from django.contrib.auth import authenticate
import re
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler

class LoginSerializer(ModelSerializer):
    username = CharField(write_only=True)
    password = CharField(write_only=True)
    class Meta:
        model = models.User
        fields = ('username', 'password')

    def validate(self, attrs):
        # user_obj = authenticate(**attrs)
        # if not user_obj:
        #     raise ValidationError('用户名或密码错误')

        # 帐号密码登陆 ==》 多方式登陆
        user = self._many_method_login(**attrs)

        # 经过user对象生成payload载荷
        payload = jwt_payload_handler(user)
        # 经过payload签发token
        token = jwt_encode_handler(payload)

        # 将user和token存放在序列化对象中,方便返回到前端去
        self.user = user
        self.token = token

        return attrs

    # 多方式登陆 (用户名、邮箱、手机号三种方式登陆)
    def _many_method_login(self, **attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        # 利用正则匹配判断用户输入的信息
        # 1.判断邮箱登陆
        if re.match(r'.*@.*', username):
            user = models.User.objects.filter(email=username).first()  # type: models.User
        # 2.判断手机号登陆
        elif re.match(r'^1[3-9][0-9]{9}$',username):
            user = models.User.objects.filter(mobile=username).first()
        # 3.用户名登陆
        else:
            user = models.User.objects.filter(username=username).first()

        if not user:
            raise ValidationError({'username': '帐号有误'})

        if not user.check_password(password):
            raise ValidationError({'password': '密码错误'})

        return user

使用postman测试代码:

5、先后台分离模式下信息交互规则

"""
1)任何人都能直接访问的接口
	请求不是是get、仍是post等,不须要作任何校验

2)必须登陆后才能访问的接口
	任何请求方式均可能作该方式的限制,请求必须在请求头中携带认证信息 - authorization
	
3)前台的认证信息获取只能经过登陆接口
	前台提供帐号密码等信息,去后台换认证信息token
	
4)前台如何完成登陆注销
	前台登陆成功通常在cookie中保存认证信息token,分离注销就是前台主动清除保存的token信息
"""

原文出处:https://www.cnblogs.com/guapitomjoy/p/11939050.html