• 过滤和分页源码、接口文档、jwt介绍和构成、base64编码、drf-jwt使用


    1 接口文档
    2 jwt介绍和构成
    3 jwt签发与认证
    4 base64编码
    5 drf-jwt使用
    5.1 django-rest-framework-jwt快速使用
    5.3 定制签发返回格式
    5.4 obtain_jwt_token源码分析

    补充

    #### 为什么在视图类中配置一个过滤类,就能走
    	-filter_backends = [SearchFilter,MyFilter]
        -GenericAPIView:继承APIVIew的视图类,是不能这样配置的----》自己过滤
        	-filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
    	-还需要继承:ListModelMixin---》它的list方法中,在对所有数据做过滤:queryset = self.filter_queryset(self.get_queryset())
        
        -self.filter_queryset如何做的过滤呢?ListModelMixin类中没有这个方法,最终从GenericAPIView中找到了
        
        -GenericAPIView的filter_queryset干了啥事?
            def filter_queryset(self, queryset):
                # 过滤类
                for backend in list(self.filter_backends):  # filter_backends视图类中配置的过滤类,列表		# 过滤类加括号---》  过滤类的对象---》调用过滤类对象的filter_queryset
                    queryset = backend().filter_queryset(self.request, queryset, self)
                return queryset
        	
    # 继承APIView---》写过滤---》可以复制GenericAPIView一些方法和属性,让我们少写代码
    
    
    
    ####  视图类中配置了分页类,为什么就有分页了?
    	- pagination_class = CommonCursorPagination  # GenericAPIView类属性
        -pagination_class是GenericAPIView的类属性:继承APIVIew的视图类,是不能这样配置的----》自己分页
        -还需要继承:ListModelMixin---》它的list方法中,在对所有数据做了分页--def list(self, request, *args, **kwargs):
            # 做过滤
            queryset = self.filter_queryset(self.get_queryset())
    		#### 分页开始
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
    		#### 分页结束### 
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)
        
        -self.paginate_queryset(queryset)是  GenericAPIView  类的方法
        
        
        - GenericAPIView的   paginate_queryset
        def paginate_queryset(self, queryset):
            if self.paginator is None:
                return None # 不做分页了
            # 做分页
            return self.paginator.paginate_queryset(queryset, self.request, view=self)
        
        -self.paginator 方法包装成了属性,就是咱们分页类的对象  CommonCursorPagination()
        @property
        def paginator(self):
            self._paginator = self.pagination_class() # 咱们配置的分页类  CommonCursorPagination
            return self._paginator
        
        - 调用了 分页类对象的paginate_queryset---》完成真正的分页
        	分页类对象.paginate_queryset(queryset, self.request, view=self)
            
            
            
    # 之前是先执行了res = exception_handler(exc, context),现在要自己做,处理drf异常
    
    
    
    # 为什么在配置文件中配置了自己写的全局异常处理函数,只要出了异常,它就会走?
    	-APIView执行流程---》dispatch的 
           try:
            except Exception as exc:
                response = self.handle_exception(exc) #看这里,exc是错误对象
                
        -执行:self.handle_exception(exc)---》self是视图类的对象
        -APIView的handle_exception(exc)
        -handle_exception源码
        
            def handle_exception(self, exc):
                exception_handler = self.get_exception_handler() # 猜 拿到的就是配置文件中配的那个函数
                response = exception_handler(exc, context) #执行这个函数,传了俩参数
                return response
            
         -self.get_exception_handler()是如何从配置文件中拿出来的
        	-self.settings.EXCEPTION_HANDLER  # 先从项目配置文件中找:key为它的EXCEPTION_HANDLER,如果项目配置文件没有,拿drf内置的配置文件
            
            
            
            
    # 如果你写了全局异常处理函数,配置好了,但是前端还没有返回固定格式,可能的原因是什么?
    	-1 这个错误不是在三大认证和视图类的方法中产生的,之前产生的--》中间件,包装新的request
        -2 你写的common_exception执行出错了
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    1 接口文档

    # 作为后端,接口写好了
    # 作为前端,需要使用我们写的接口(移动端,web,桌面端)
    
    # 后端需要写接口文档
    
    
    # 接口文档的展现形式:
    	1 word ,md ,写好传到公司的某个平台---》前端可以下载
        2 自动生成接口文档---》后端通过配置--》把所写的接口都自动生成---》地址--》访问这个地址就能看到所有接口文档
        
        3 公司内部搭建接口文档平台
        	- 开源:Yapi--->同学搭建一个,给搭建用
                -https://zhuanlan.zhihu.com/p/366025001
            - 自己开发(自研)
            
        4 使用第三方平台(花钱)-->showdoc ....
    
    # 接口文档如何写?需要有哪些东西?
    	-以用户注册接口为例:
        	1 接口描述
            2 请求地址
            3 请求方式
            4 编码格式:json,urlencoded,form-data
            5 请求参数:参数详解
            	-请求地址参数
                -请求体参数
    		6 返回格式示例--》返回参数说明
            7 备注(可有可无)--》错误码
            
            
    # 自动生成接口文档
    	-coreapi,swagger:drf-yasg
        
        
    # coreapi自动生成
    第一步:pip install coreapi
    第二步:设置接口文档访问路径
    from rest_framework.documentation import include_docs_urls
    urlpatterns = [
        ...
        path('docs/', include_docs_urls(title='站点页面标题'))
    ]
    
    第三步:在视图中,加注释
    
    第四步:配置文件配置
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    2 jwt介绍和构成

    # 做会话保持的发展历史
    	-https://www.cnblogs.com/liuqingzheng/p/8990027.html
    
    # jwt:Json Web Token:web方向的token认证方案
    # 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证(token串)。我们不再使用Session认证机制,而使用Json Web Token(本质就是token)认证机制
    
    # Json web token (JWT), JWT用在咱们前后端做登录认证的,如果登录了,就携带token过来,如果没登录,就不携带---》后端通过验证token的准确性,确定是谁访问我们
    
    
    #JWT的构成--三部分
    	eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
        
        # 头:header
        	-一般放公司信息,加密方式(没放秘钥)
        # 荷载:payload
        	-当前用户的信息:用户名,用户id,token过期时间。。。
        # 签名:signature
        	-第一部分和第二部分通过加密得到的字符串
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3 jwt签发与认证

    # 以后使用jwt,最核心的就是写两个地方
    	-签发:(登录接口)
        	-登录接口,登录成功,签发token(三段式)
            -header,用base64编码,暂放
                {"company": "公司信息",}
            -payload,用base64编码,暂放
            	{用户名,用户权限,过期时间}
            -使用加密方式:md5,把header和payload 都update进md5中---》生成前面---》base64编码
            
            -三段拼接起来---》用 .  分割 
            
            
        -认证(认证类)
        	-用户携带token过来,认证
            -取出第一部分header
            -取出第二部分 payload
            -使用之前同样的加密算法(密码),得到新前面
            -跟token的第三部分比较,如果一样,表示没有被窜改,顺利继续往下走,返回两个值
            -如果被篡改了,抛异常
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4 base64编码

    # base64 编码
    
    # 作用,用途:
    	1 token串使用base64编码
        2 互联网中前后端数据交互,可以使用base64编码
        3 图片二进制可以使用base64编码传递
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    import json
    import base64
    img=''
    
    
    
    # base64 的编码和解码(字符串)
    ###编码
    # d={'name':'lqz','age':19}
    # d_str=json.dumps(d)
    # res=base64.b64encode(d_str.encode('utf-8'))  # 字符串转bytes格式
    # print(res)  # eyJuYW1lIjogImxxeiIsICJhZ2UiOiAxOX0=
    # base64编码字符串长度必须是4的倍数,如果不足,用= 补齐,= 一定不会超过3个
    # 解码
    # res=base64.b64decode('eyJuYW1lIjogImxxeiIsICJhZ2UiOiAxOX0=')
    # print(res)
    
    
    
    ##把图片保存到本地
    res=base64.b64decode(img)
    with open('xx.png','wb') as f:
        f.write(res)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    5 drf-jwt使用

    # django 中使用jwt
    
    # 可以自己写,使用第三方
    	-django-rest-framework-jwt:有点老
        -djangorestframework-simplejwt:新的
        -自己写:https://gitee.com/liuqingzheng/rbac_manager/blob/master/libs/lqz_jwt/token.py
        
    # 下载:
    pip install djangorestframework-jwt
    	
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    5.1 django-rest-framework-jwt快速使用

    # 签发:默认使用auth的user表签发--》登录接口--人家帮咱们写了
        from rest_framework_jwt.views import obtain_jwt_token # 这就是个登录接口,人家帮你写好了
        urlpatterns = [
            path('login/', obtain_jwt_token),
        ]
        
    # 认证--》认证类
    	-视图类上,配置认证类和权限类
        	authentication_classes = [JSONWebTokenAuthentication,]
        	permission_classes = [IsAuthenticated]
    	
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    5.3 定制签发返回格式

    # 自定义认证返回结果
    
    # 写个函数
    def jwt_response_payload_handler(token, user=None, request=None):
        return {
            'status': 100,
            'msg': '登录成功',
            'token': token,
            'username': user.username
        }
    
    # 配置文件配置
    JWT_AUTH = {
        'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.response.jwt_response_payload_handler',
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    5.4 obtain_jwt_token源码分析

    #为什么 路由这样配了,就会有个登录接口
     	path('login/', obtain_jwt_token),
        
    #obtain_jwt_token 本质是ObtainJSONWebToken.as_view()
    
    # 本质是ObtainJSONWebToken
    class ObtainJSONWebToken(JSONWebTokenAPIView):
        serializer_class = JSONWebTokenSerializer
        
    # 向login发送post请求,ObtainJSONWebToken一定有个post方法
    
    # 在父类中:JSONWebTokenAPIView  post
    	-登录走的是JSONWebTokenAPIView的post,签发token 是在序列化类中
        -签发完token执行了,咱们写的jwt_response_payload_handler,所以才能定制返回格式
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    uni-app 如何优雅的使用权限认证并对本地文件上下起手
    vue自定义指令
    ctfshow unserialize
    Java版本spring cloud + spring boot企业电子招投标系统源代码
    ESP8266 WiFi物联网智能插座—上位机和下位机通信协议
    CocoaPods 在iOS开发中养活了这么多项目,它到底是个啥?
    【C++】内联函数 ③ ( C++ 编译器 不一定允许内联函数的内联请求 | 内联函数的优缺点 | 内联函数 与 宏代码片段对比 )
    Acwing 286. 选课(背包类树形DP)
    2000-2021年三批“智慧城市”试点名单匹配数据
    电商平台APP商品详情源数据接口代码分享
  • 原文地址:https://blog.csdn.net/weixin_44145338/article/details/132766375