• JWT安装与配置


    1.登录接口
    2.刷新接口
    3.自定义返回格式

    1.JWT安装配置

    1.1 安装JWT
    pip install djangorestframework-jwt==1.11.0
    
    1.2 syl/settings.py 配置jwt载荷中的有效期设置
    import datetime
    # jwt载荷中的有效期设置
    JWT_AUTH = {
        # 1.token前缀:headers中 Authorization 值的前缀
        'JWT_AUTH_HEADER_PREFIX': 'JWT',
        # 2.token有效期:一天有效
        'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
        # 3.刷新token:允许使用旧的token换新token
        'JWT_ALLOW_REFRESH': True,
        # 4.token有效期:token在24小时内过期, 可续期token
        'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(hours=24),
        # 5.自定义JWT载荷信息:自定义返回格式,需要手工创建
        'JWT_RESPONSE_PAYLOAD_HANDLER': 'user.utils.jwt_response_payload_handler',
    }
    
    1.3 syl/settings.py JWT结合DRF进行认证权限配置
    REST_FRAMEWORK = {
           # 用户登陆认证方式
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework_jwt.authentication.JSONWebTokenAuthentication', # 在 DRF中配置JWT认证
            # 'rest_framework.authentication.SessionAuthentication',  # 使用session时的认证器
            # 'rest_framework.authentication.BasicAuthentication'  # 提交表单时的认证器
        ],
        # 2.权限配置(全局): 顺序靠上的严格
        'DEFAULT_PERMISSION_CLASSES': [
            # 'rest_framework.permissions.IsAdminUser',  # 管理员可以访问
            'rest_framework.permissions.IsAuthenticated',  # 认证用户可以访问
            # 'rest_framework.permissions.IsAuthenticatedOrReadOnly',  # 认证用户可以访问, 否则只能读取
            # 'rest_framework.permissions.AllowAny',  # 所有用户都可以访问
        ],
    
    }
    
    1.4 user/urls.py 增加获取token接口和刷新token接口
    from user import views
    from rest_framework_jwt.views import obtain_jwt_token,refresh_jwt_token
    
    # router = SimpleRouter()    # 没有跟路由 /user/ 无法识别
    router = DefaultRouter()     # 有根路由
    router.register(r'user',UserViewSet)   # 配置路由
    
    urlpatterns = [
        path('login/',obtain_jwt_token),    # 获取token,登录视图
        path('refresh/',refresh_jwt_token),
        path('api-auth/',include('rest_framework.urls',namespace='rest_framework')),  #认证地址
    ]
    
    urlpatterns += router.urls   # 模块地址
    
    
    1.5 在user/utils.py中从写jwt_response_payload_handler
    def jwt_response_payload_handler(token, user=None, request=None, role=None):
        if user.first_name:
            name = user.first_name
        else:
            name = user.username
        return {
            'authenticated': 'true',
            'id': user.id,
            "role": role,
            'name': name,
            'username': user.username,
            'email': user.email,
            'token': token,
        }
    

    2.postman测试接口

    2.1 测试登录接口,获取token
    http://192.168.56.100:8888/user/login/
    

        # 1. 认证:自定义认证类,自定义会覆盖全局配置
        authentication_classes = (JSONWebTokenAuthentication,)
        # 2. 权限:自定义权限类     开启登录验证
        permission_classes = (MyPermission,)
    
    2.2 使用获得的token获取所有用户信息
    http://192.168.56.100:8888/user/user/
    

    源码分析

     class JSONWebTokenAPIView(APIView):
         """ 
         Base API View that various JWT interactions inherit from. 
         """
         permission_classes = () 
         authentication_classes = ()
         def get_serializer_context(self): 
             """ 
             Extra context provided to the serializer class. 
             """ 
             return {
                 'request': self.request, 
                 'view': self, 
             }
         def get_serializer_class(self):
             """ 
             Return the class to use for the serializer. 
             Defaults to using `self.serializer_class`. 
             You may want to override this if you need to provide different 
             serializations depending on the incoming request. 
             (Eg. admins get full serialization, others get basic serialization) 
             """ 
             assert self.serializer_class is not None, ( 
                 "'%s' should either include a `serializer_class` attribute, " 
                 "or override the `get_serializer_class()` method." 
                 % self.__class__.__name__) 
             return self.serializer_class
         def get_serializer(self, *args, **kwargs): 
             """ 
             Return the serializer instance that should be used for validating and 
             deserializing input, and for serializing output. 
             """ 
             serializer_class = self.get_serializer_class() 
             kwargs['context'] = self.get_serializer_context() 
             return serializer_class(*args, **kwargs)
         def post(self, request, *args, **kwargs): 
             serializer = self.get_serializer(data=request.data) 
    
             if serializer.is_valid(): 
                 user = serializer.object.get('user') or request.user # User表对象 
                 token = serializer.object.get('token') # 获取到生成的token 
                 response_data = jwt_response_payload_handler(token, user, request)
                 response = Response(response_data) 
                 if api_settings.JWT_AUTH_COOKIE: 
                     expiration = (datetime.utcnow() +       
                                   api_settings.JWT_EXPIRATION_DELTA) 
                     response.set_cookie(api_settings.JWT_AUTH_COOKIE, 
                                         token, 
                                         expires=expiration,             
                                         httponly=True) 
                 return response 
    
             return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)
    
  • 相关阅读:
    android29
    android28
    android27
    android26
    Dynamics CRM2011 MspInstallAction failed when installing an Update Rollup
    Dynamics CRM Import Solution Attribute Display Name description is null or empty
    The service cannot be activated because it does not support ASP.NET compatibility
    IIS部署WCF报 无法读取配置节“protocolMapping”,因为它缺少节声明
    Unable to access the IIS metabase.You do not have sufficient privilege
    LM算法与非线性最小二乘问题
  • 原文地址:https://www.cnblogs.com/Beginner-Y/p/13771789.html
Copyright © 2020-2023  润新知