• drf jwt认证组件


    常用的前后台分类认证 - jwt(json web token)

    一、jwt认证规则

    • 全称:json web token
    • 解释:加密字符串的原始数据是json,后台产生,通过web传输给前台存储
    • 格式:三段式
      • 头(Header)、载荷(Payload)、签名(Signature)、
      • 头和载荷采用的是base64可逆加密,签名才有md5不可逆加密
    • 内容:
      • 头(基础信息,也可以为空):加密方式、公司信息、项目组信息、...
      • 载荷(核心信息):用户信息、过期时间、...
      • 签名(安全保障):头加密结果+载荷加密结果+服务器秘钥 的md5加密结果
    • 认证规则:
      • 后台一定要保障 服务器秘钥 的安全性(它是jwt的唯一安全保障)
      • 后台签发token -> 前台存储 -> 发送需要认证的请求带着token -> 后台校验得到合法的用户

    1.1 为什么要有jwt认证

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

    二、jwt模块

    • 安装:pip install djangorestframework-jwt

    • 模块包名:rest_framework_jwt

    三、jwt模块使用

    • 有了drf-jwt框架后,后期任务只需要重写登录即可:
      • 为什么要重写登录:drf-jwt只完成了账号密码登录,我们还需要手机登录,邮箱登录
      • 为什么不需要重写认证类:因为认证规则已经完成且固定不变,变得只有认证字符串的前缀,前缀可以在配置文件中配置

    使用提供好的 jwt视图类三个接口:

    • 签发token接口、校验token、刷新token

      注:jwt视图类签发token的接口会帮你完成登陆并签发token,但drf-jwt只完成了账号密码登录,我们还需要手机登录,邮箱登录,就需要去重写jwt序列化类签发token实现多方式登录

      '''urls.py'''
      # 使用JWT认证组件实现好的视图
      from rest_framework_jwt.views import ObtainJSONWebToken,obtain_jwt_token
      urlpatterns = [
          # 使用JWT认证组件实现好的视图类来实现登陆认证
          # url(r"jwt_login/$",ObtainJSONWebToken.as_view())
          # jwt提供的简写形式
          url(r"jwt_login/$",obtain_jwt_token),
          url(r"jwt_refresh/$",refresh_jwt_token),
          url(r"jwt_verify/$",verify_jwt_token),
      ]
      

    drf全局配置jwt认证组件

    # drf的配置
    REST_FRAMEWORK = {
        # 认证组件的全局配置
        'DEFAULT_AUTHENTICATION_CLASSES':[
            # jwt认证类
            'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        ],
    }
    

    drf-jwt配置

    # drf-jwt配置
    import datetime
    JWT_AUTH = {
        # token过期时间
        'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
        # 允许刷新
        # 'JWT_ALLOW_REFRESH': True,
        # # 刷新后的最大过期时间
        # 'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
        # 认证前缀
        'JWT_AUTH_HEADER_PREFIX': 'JWT',
    }
    

    重写jwt序列化类签发token实现多方式登录

    '''serializers.py'''
    
    # 导入JWT认证
    from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
    import re
    class LoginJWTModelSerializer(serializers.ModelSerializer):
        username = serializers.CharField(write_only=True)
        password = serializers.CharField(write_only=True)
    
        class Meta:
            model = models.UserInfo
            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)     # 使用jwt认证模块,根据当前用户得到载荷
            token = jwt_encode_handler(payload)     # 使用jwt认证模块,得到token
    
            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.UserInfo.objects.filter(email=username).first()
    
            elif re.match(r'^1[3-9][0-9]{9}$', username):
                user = models.UserInfo.objects.filter(mobile=username).first()
            else:
                user = models.UserInfo.objects.filter(username=username).first()
    
            if not user:
                raise serializers.ValidationError({'username': '账号有误'})
    
            if not user.check_password(password):
                raise serializers.ValidationError({'password': '密码有误'})
    
            return user
    
    '''views.py'''
    
    '''
    jwt 模块实现 签发token
    重写jwt序列化类签发token实现多方式登录
    '''
    class JWTLoginAPIView(APIView):
        # 登陆 禁用认证和权限校验
        authentication_classes = []
        permission_classes = []
        def post(self, request, *args, **kwargs):
            ser_obj = serializers.LoginJWTModelSerializer(data=request.data)
            ser_obj.is_valid(raise_exception=True)
            return common.APIResponse(results={
                "username": ser_obj.user.username,
                "token" : ser_obj.token,
            })
    

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

    """
    1)任何人都能直接访问的接口:
    	请求不管是get、还是post等,不需要做任何校验
    
    2)必须登录后才能访问的接口:
    	任何请求方式都可能做该方式的限制,请求必须在请求头中携带认证信息 - authorization
    	
    3)前台的认证信息获取只能通过登录接口:
    	前台提供账号密码等信息,去后台换认证信息token
    	
    4)前台如何完成登录注销:
    	前台登录成功一般在cookie中保存认证信息token,分离注销就是前台主动清除保存的token信息
    """
    
  • 相关阅读:
    SQL server 导出平面文件时出错: The code page on Destination
    中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030
    C# DataTable 转 List(大家进来讨论讨论)
    CSS3圆角气泡框,评论对话框
    WinForm 换行问题 textbox (转)
    Nhibernate 多对多级联删除
    JS、C# 去除html标签
    Nhibernate 多对多级联更新
    Ext.Ajax.request()方法和FormPanel.getForm().submit()方法,都返回success()方法的差异
    ExtJs 4.2.1 报错:Uncaught TypeError: Cannot call method 'getItems' of null
  • 原文地址:https://www.cnblogs.com/XuChengNotes/p/11938862.html
Copyright © 2020-2023  润新知