其他分享
首页 > 其他分享> > drf RBAC介绍 jwt介绍和快速使用和接口文档

drf RBAC介绍 jwt介绍和快速使用和接口文档

作者:互联网

内容详细

1 RBAC


        # python用来做公司内部项目居多,人事系统,进销存,报销审批,自动化运维
            -公司内部项目对执行效率要求不高(人少)
          -对开发效率要求高(越快开发出越好,成本越低越好)
          -知乎,豆瓣用python写的---》随着用户量增大---》切换语言
        # 对外的权限比较简单:普通注册用户,VIP用户,超级VIP  --》优酷,网易云音乐,百度网盘
        # 公司内部系统:通常使用RBAC的权限控制
                -公司内有部门(开发部,运维部,市场部,总裁办,人力资源部门)
            -权限和角色(部门)绑定   
            -举个例子:发工资权限,招人权限,开发代码权限---》招人权限,发工资权限给人力资源--》开发代码权限给开发部门



        # RBAC  是基于角色的访问控制(Role-Based Access Control )在 RBAC  中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。

        # 权限赋予给角色(部门),而把角色(部门)又赋予用户

        # 针对于公司内部项目,后台管理居多(运营在使用),使用rbac居多
        # django-vue-admin:后端用drf,前端用vue,权限管理的 脚手架---》前后端分离
        # django的admin---》混合的后台管理用的多---》基于django的admin二次开发
        # simpleui:对django admin的美化

        # django的admin自带rbac权限管理(表设计完成权限管理)---》6张表
            -用户表
          -角色表(组表,部门表)
          -权限表
          ----------
          -角色和权限多对多中间表
          -用户和角色多对多中间表
          -----django-admin中多了一张表-----
          用户对权限多对多中间表



        ### 基于django的admin做二次开发,开发出公司内部的管理系统
            -纯基于原生
            -使用第三方美化:xadmin(早就不维护了,弃坑了),simpleui(国内的,主流),国外也有很多

        # 在关系型数据库的关系中:只有三种---》本质只有一种:外键关系
            -一对多
            -多对多
            -一对一

        # 前后端分离,验证码如何实现?写验证码接口

image-20220407104005586

2 自动生成接口文档

        # 顺利的写接口----》在公司里,前端和后端是两拨人写---》咱们后端接口写好了,我们知道接口怎么用

        127.0.0.1:8080/user/login--->post--->{"username":'lqz','pwd':123}--->{status:100,msg:登陆成功,token:dafasdf}


        # 后端人,需要写出接口文档,给前端用,前端按照接口文档去开发
        # 具体格式可以参照:https://open.weibo.com/wiki/2/comments/show


        # 如何写?
            -第一种:使用word或者md文档编写---》纯手写---》好的公司这么用
          -第二种:第三方平台录入---》半手写-->https://blog.csdn.net/weixin_44337261/article/details/121005675-->部分公司
          -第三种:公司自己开发接口平台,搭建接口平台--》数据放在公司自己--》学长公司在用
            -https://zhuanlan.zhihu.com/p/366025001

          -第四种:自动生成接口文档---》用的少---》自动生成+导出---》录入到yapi
            -coreapi,swagger


        # coreapi 使用步骤
            -pip3 install coreapi
            -路由中写
            from rest_framework.documentation import include_docs_urls
            urlpatterns = [
                ...
                path('docs/', include_docs_urls(title='站点页面标题'))
            ]

          -写视图类,只需要加注释即可

          -在配置文件中:
          REST_FRAMEWORK = {
         'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
            # 新版drf schema_class默认用的是rest_framework.schemas.openapi.AutoSchema
        }

          -访问地址:http://127.0.0.1:8000/docs/
          -给前端,前端按照这个接口文档开发
          -基于这个,录入到第三方接口平台,自己写word文档



          # 如何写好接口文档
          http://www.liuqingzheng.top/article/1/02-%E5%A6%82%E4%BD%95%E5%86%99%E5%A5%BD%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3/

3 jwt介绍和快速使用

        # cookie,session,token的区别?
        https://www.cnblogs.com/liuqingzheng/articles/8990027.html
        # 认证:session机制:需要在后端存储数据---》之前使用的django-session
        # 如果登录用户很多,需要在后端存很多数据,频繁查询数据库,导致效率低---》能不能想一种方案,不在服务端存数据---》客户端存数据(数据安全)---》token认证机制


        # Json web token (JWT),token是一种认证机制,用在web开发方向,叫jwt

        # JWT的构成---》三段式---》每一段都使用base64编码
            -典型的jwt串样子,通过. 分隔成三段:
         eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
            -第一段:头:声明类型,这里是jwt,声明加密的算法,公司信息等等。。。 ---》 目前作用不大
          -第二段:荷载(payload):有效信息
                -用户名,用户id,登陆时间,token失效时间。。。。
          -第三段:签名(signature):通过  头+荷载 使用某种加密方式加密后得到的



        # base64编码和解码---》只是编码和解码,不能叫加密
        import base64

        # 编码
        # s = b'''{"name":"lqz","age":19}'''
        # res = base64.b64encode(s)
        # print(res)  # eyJuYW1lIjoibHF6IiwiYWdlIjoxOX0=

        # 解码
        # s=b'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9'
        # res=base64.b64decode(s)
        # print(res)



        ## jwt的签发和认证---》保证安全
        # 签发---》登陆过程---》如果没有第三方模块帮助我们做,我们就自己做
        """
        1)用基本信息公司信息存储json字典,采用base64算法得到 头字符串
        2)用关键信息存储json字典,采用base64算法得到 荷载字符串,过期时间,用户id,用户名
        3)用头、体加密字符串通过加密算法+秘钥加密得到 签名字符串
        拼接成token返回给前台
        """


        # 认证---》访问需要登陆的接口
        """
        1)将token按 . 拆分为三段字符串,第一段 头加密字符串 一般不需要做任何处理
        2)第二段 体加密字符串,要反解出用户主键,通过主键从User表中就能得到登录用户,过期时间是安全信息,确保token没过期
        3)再用 第一段 + 第二段 + 加密方式和秘钥得到一个加密串,与第三段 签名字符串 进行比较,通过后才能代表第二段校验得到的user对象就是合法的登录用户
        """

        # 大部分的web框架都会有第三方模块支持----》如果没有需要自己写
        django中有一个django-rest-framework-jwt,咱们讲的:
        # https://github.com/jpadilla/django-rest-framework-jwt
        django中有一个,django-rest-framework-simplejwt,咱们不讲,公司可能会用:
        # https://github.com/jazzband/djangorestframework-simplejwt

        # 区别
        # https://blog.csdn.net/lady_killer9/article/details/103075076

3.1 django中快速使用jwt

3.1.1 签发

        # 第一步:pip3 install djangorestframework-jwt
        # 第二步:在路由中配置
        from rest_framework_jwt.views import obtain_jwt_token
        urlpatterns = [
            path('login/', obtain_jwt_token),
        ]

        # 第三步:使用接口测试工具发送post请求到后端,就能基于auth的user表签发token
        {
            "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoyLCJ1c2VybmFtZSI6InB5eSIsImV4cCI6MTY0OTMxNjc3MiwiZW1haWwiOiIzMDYzMzQ2NzhAcXEuY29tIn0.YOUc9gcFIQf9FBibZJANaI3Rmpw4zfMy1e8ez1roKSI"
        }


        # 比session优势在不需要在后端存数据了,jwt不会在后端存数据,保证了数据安全

        ### 会有被别人窃取的风险----》只能拿到和使用---》避免不了窃取后使用,只能避免别人篡改不了---》爬虫就是干这事,扣除token串,模拟发请求----》如果你能想一种方式,避免别人获取了token串,不能发请求---》你整个就把爬虫行业干掉了

3.1.2 认证

        # 视图类的某个方法,访问时候,需要认证通过才能访问---》写认证类-->我们用了第三方模块---》第三方模块写了一个认证类



        # 在视图类中配置:认证类+权限类
        from rest_framework_jwt.authentication import JSONWebTokenAuthentication
        from rest_framework.permissions import IsAuthenticated
        class BookView(GenericViewSet,ListModelMixin):
            # JSONWebTokenAuthentication :rest_framework_jwt模块写的认证类
            authentication_classes = [JSONWebTokenAuthentication,]
            # 需要配合一个权限类
            permission_classes = [IsAuthenticated,]


        ### 在前端使用的时候,要携带token,token携带方式:---》为什么要按这个格式?人家的认证类已经写完了,就是去请求头中取的,按固定规则取的,所以咱们需要按照这个格式
        ## 后期咱么要自己基于自定义的User表,签发token,和自定义认证类
        在请求头中使用  Authorization : jwt token串

4 jwt定制返回格式

        # 签发token,其实就是jwt模块基于auth的user表,帮咱们写了一个登陆功能,但是一般请求,我们登陆成功后,返回的数据更多 {code:100,msg:登陆成功,token:adfadf,username:pyy}

        # 定义签发token(登陆接口)返回格式
            -第一步:写一个函数--->返回什么格式,前端就能看到什么格式
            def jwt_response_payload_handler(token, user=None, request=None):
            return {
                'code': 100,
                'msg': "登陆成功",
                'token': token,
                'username': user.username

            }
          -第二步:在配置文件中配置
          # jwt模块的配置文件,统一放在JWT_AUTH
          JWT_AUTH = {
              'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.utils.jwt_response_payload_handler',
          }

image-20220407164501971

5 jwt源码分析

        # 签发源码
        obtain_jwt_token---》ObtainJSONWebToken.as_view():视图类.as_view()--->ObtainJSONWebToken视图类---》登陆post请求,携带用户名密码---》视图类中有post方法
        # 视图类中的序列化类: serializer_class = JSONWebTokenSerializer---》全局钩子中获取当前登录用户和签发token
        # post方法中:serializer = self.get_serializer(data=request.data)


        ### 你会的:obtain_jwt_token---》ObtainJSONWebToken视图类---》post方法--》通过前端传入的用户名和密码拿到了当前用户,通过当前用户签发了token---》返回给了前端


        # 认证源码
            -认证类---》authenticate方法---》验证
          def authenticate(self, request):
                jwt_value = self.get_jwt_value(request) # 获取真正的token,三段式
                if jwt_value is None: # 如果没传token,就不认证了,直接通过,所以需要配合权限类一起用
                    return None

                try:
                    payload = jwt_decode_handler(jwt_value)# 验证签名
                except jwt.ExpiredSignature:
                    msg = _('Signature has expired.') # 过期了
                    raise exceptions.AuthenticationFailed(msg)
                except jwt.DecodeError:
                    msg = _('Error decoding signature.')# 被篡改了
                    raise exceptions.AuthenticationFailed(msg)
                except jwt.InvalidTokenError:
                    raise exceptions.AuthenticationFailed()# 不知名的错误

                user = self.authenticate_credentials(payload)

                return (user, jwt_value)
		了解:
		3 看博客cookie,session,token:https://www.cnblogs.com/liuqingzheng/articles/8990027.html

		4 自己搭建一个yapi:https://zhuanlan.zhihu.com/p/366025001

标签:---,jwt,接口,django,RBAC,token,权限,drf
来源: https://www.cnblogs.com/ydy001/p/16299305.html