JWT认证

JWT认证

工作原理

1)jwt = base64(头部).base(载荷).hash256(base64(头部).base(载荷).密钥)
2) base64是可逆算法、hash256是不可逆算法
3)密钥是固定的字符串,保存在服务器
'''
1) 服务器不要存储token, token 交个每一个客户端来存储
2)服务器存储的是 签发和校验token 两段算法,签发认证效率高
3)算法完成各集群服务器同步低,路由项目完成集群部署(适应高并发)
'''

格式

'''
1) jwt token 采用三段式: abc(头部).123(载荷).xyz(签名)
2)没一部分都是一个json字典加密形成的字符串
3)头部和载荷采用的是base64可逆加密(前台和后台都可以解密)
4)签名采用的是hash256不可逆加密(后台校验采用碰撞校验)
5)各部分字典的内容:
    头部:基础信息 - 公司信息、项目组信息、可逆加密采用的算法
    载荷:有用单非私密的信息 - 用户可公开信息、过期时间
    签名:头部+载荷+密钥 不可逆加密后的结果
    注: 服务器jwt签名加密密钥一定不能泄露

签发token:固定的头部信息加密、当前的登录用户与过期时间加密.头部+载荷+密钥生成不可逆加密

校验token: 头部可校验可不校验,载荷校验出用户与过期时间,头部+载荷+密钥完成碰撞检测校验token是否被篡改

'''

drf-jwt

安装

pip install djangorestframework-jwt

手动签发token

# 1) 通过 username 和 password得到user对象
# 2) 通过user对象生成payload: jwt_payload_handler(user) => payload
# from rest_framework_jwt.serializers import jwt_payload_handler
# 3) 通过payload 签发token: jwt_encode_handler(payload) => token
# from rest_framework_jwt.serializers imiport jwt_encode_handler

手动校验token

serializers

import re

from rest_framework import  serializers
from .models import User
from rest_framework_jwt.serializers import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

class UserModelSerializer(serializers.ModelSerializer):
    # 自定义反序列化字段
    usr = serializers.CharField(write_only=True)
    pwd = serializers.CharField(write_only=True)
    class Meta:
        model = User
        fields = ['usr', 'pwd']
        extra_kwargs = {
        }

    def validate_usr(self, value):
        return value

    def validate_pwd(self, value):
        return value

    def validate(self, attrs):
        usr = attrs.get('usr')
        pwd = attrs.get('pwd')
        if re.match('.*@.*', attrs['usr']):
            user = User.objects.filter(email=usr).first()
        elif re.match('1[3-9][0-9]{9}', usr):
            user = User.objects.filter(mobile=usr).first()
        else:
            user = User.objects.filter(username=usr).first()
        if user and user.check_password(pwd):
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            self.user = user
            self.token = token
            return attrs
        raise serializers.ValidationError({'data': '数据有误'})


views.py

from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin, CreateModelMixin
from utils.response import APIResponse
from . import models, serializer


# 实现多方式登录签发token:账号、手机号、邮箱 登录
# 1) 禁用认证与权限组件
# 2) 拿到前台登录信息
# 3) 校验得到登录用户
# 4)  签发token并返回
class LoginAPIView(APIView):

    authentication_classes = []
    permission_classes = []

    def post(self, request, *args, **kwargs):

        user_ser = serializer.UserModelSerializer(data=request.data)
        user_ser.is_valid(raise_exception=True)
        return APIResponse(token=user_ser.token, results=serializer.UserModelSerializer(user_ser.user).data)
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。