• day 82 jwt模块


    jwt认证规则

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


    认证规则:
    后台一定要保障 服务器秘钥 的安全性(它是jwt的唯一安全保障)
    后台签发token -> 前台存储 -> 发送需要认证的请求带着token -> 后台校验得到合法的用户


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

    前后台分离模式下信息交互规则

    1)任何人都能直接访问的接口
    请求不是是get、还是post等,不需要做任何校验

    2)必须登录后才能访问的接口
    任何请求方式都可能做该方式的限制,请求必须在请求头中携带认证信息 - authorization

    3)前台的认证信息获取只能通过登录接口
    前台提供账号密码等信息,去后台换认证信息token

    4)前台如何完成登录注销
    前台登录成功一般在cookie中保存认证信息token,分离注销就是前台主动清除保存的token信息

    知识点总结

    1、jwt认证:三段式的格式、每一段的内容、由后台签发到前台存储再到传给后台校验的认证流水线

     登陆视图

    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):
    serializer = serializers.LoginSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    return APIResponse(msg='login success', data={
    'username': serializer.user.username,
    'token': serializer.token
    })


    序列化,并且在全局钩子中签发token
    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')

    # 在全局钩子中签发token
    def validate(self, attrs):
    # user = authenticate(**attrs)
    # 账号密码登录 => 多方式登录
    user = self._many_method_login(**attrs)

    # 签发token,并将user和token存放到序列化对象中
    payload = jwt_payload_handler(user)
    token = jwt_encode_handler(payload)

    self.user = user
    self.token = token
    return attrs

    校验多种登陆方式
    # 多方式登录
    def _many_method_login(self, **attrs):
    username = attrs.get('username')
    password = attrs.get('password')
    if re.match(r'.*@.*', username):
    user = models.User.objects.filter(email=username).first() # type: models.User

    elif re.match(r'^1[3-9][0-9]{9}$', username):
    user = models.User.objects.filter(mobile=username).first()
    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


    # 只参与序列化
    class UserModelSerializer(ModelSerializer):
    # 改了原数据库字段的序列化方式
    password = SerializerMethodField()
    def get_password(self, obj):
    return '########'
    class Meta:
    model = models.User
    fields = ('username', 'password', 'mobile', 'email', 'first_name', 'last_name')

    2、drf-jwt插件:
    三个接口:签发token、校验token、刷新token
    自定义jwt插件的配置

     url(r'^login/$', obtain_jwt_token),
    url(r'^verify/$', verify_jwt_token),
    url(r'^refresh/$', refresh_jwt_token),

    3、使用jwt插件完成多方式登录
    视图类:将请求数据交给序列化类完成校验,然后返回用户信息和token(从序列化对象中拿到)
    序列化类:自定义反序列化字段,全局钩子校验数据得到user和token,并保存在序列化类对象中
    token可以用jwt插件的rest_framework_jwt.serializers中
    jwt_payload_handler,jwt_encode_handler
    完成签发

    序列化,并且在全局钩子中签发token
    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')

    # 在全局钩子中签发token
    def validate(self, attrs):
    # user = authenticate(**attrs)
    # 账号密码登录 => 多方式登录
    user = self._many_method_login(**attrs)

    # 签发token,并将user和token存放到序列化对象中
    payload = jwt_payload_handler(user)
    token = jwt_encode_handler(payload)

    self.user = user
    self.token = token
    return attrs

    4、自定义频率类完成视图类的频率限制
    1)定义类继承SimpleRateThrottle,重写get_cache_key方法,设置scope类属性
    2)scope就是一个认证字符串,在配置文件中配置scope字符串对应的频率设置
    3)get_cache_key的返回值是字符串,该字符串是缓存访问次数的缓存key

    REST_FRAMEWORK={
    'DEFAULT_THROTTLE_RATES': {
    'three': '3/min',
    }}


    # 自定义频率类
    from rest_framework.throttling import SimpleRateThrottle
    # 1)定义类继承SimpleRateThrottle,重写get_cache_key方法,设置scope类属性
    # 2)scope就是一个认证字符串,在配置文件中配置scope字符串对应的频率设置
    # 3)get_cache_key的返回值是字符串,该字符串是缓存访问次数的缓存key
    class ThreeTimeUserThrottle(SimpleRateThrottle):
    scope = 'three'
    # 当前用户缓存的key
    def get_cache_key(self, request, view):
    return 'throttle:user_%s' % (request.user.id)
  • 相关阅读:
    2.字符设备驱动开发
    1.Linux内核模块编程
    Linux基础知识
    数据结构小结
    3基本概念
    2在HTML中使用JavaScript
    1JavaScript简介
    20161230【作业1】静态网页制作笔记
    14非屏幕媒体
    13用户界面样式
  • 原文地址:https://www.cnblogs.com/wwei4332/p/11938311.html
Copyright © 2020-2023  润新知