drf11-jwt-RBAC-CAsbin-simplui

排序和过滤源码分析

1.基于jwt的认证类

2.RBAC的介绍和使用

ACL,RBAC,ABC(PBAC,CBAC)权限控制的介绍

:方便我们能快速做权限控制(ac,rbac。。。)

model.conf

policy.csv

3.后台管理simplui的介绍和使用

settings

admin.py

排序和过滤源码分析

继承了GenericAPIView + ListModelMixin,只是在视图类配置filter_backends它就能实现过滤和排序
-drf内置的过滤类(searchFilter)
-django-filter
-自定义:写一个类,继承BaseFilterBackend,重写filter_queryset,
返回qs对象,就是过滤或排序后的
#只有获取多有才涉及到排序
	-list方法
	def list(self,request,*args,**kwargs):
		#self.get_queryset()所有数据,经过了self.filter_queryset
		返回了qs
		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_oaginatated_response(serializer.data)
		#如果没有分页,走正常的序列化,返回
		serializer = self.ger_serializer(queryset,many=True)
		return Response(serializer.data)
		
		
		-self.filter_queryset完成了过滤,当前在视图类中,self是视图类对象,去视图类中没找到,去父类---》GenericAPIView--》filter_queryset
		
		def filter_queryset(self,queryset):
			for backend in list(self.filter_backends):
				queryset = backend().filter_queryset(self.request,queryset,self)
			return queryset

总结:

​ -写的过滤类要重写filter_queryset,返回qs(过滤或排序后)对象
​ -后期如果不写过滤类,只要在视图类中重写filter_queryset,在里面实现过滤也可以

1.基于jwt的认证类、

class JWTAuthentication(BaseAuthentication):
	def authticate(self,request):
		#放到头中:token--->HTTP_TOKEN,authorization----HTTP_AUTHORIZATION
		print(request.META)
		jwt_value =request.META.get('HTTP_TOKEN')
		#验证token是否合法,jwt模块下一定有个验证token的函数
        try:
            payload = jwt_decode_handler(jwt_value)
        except jwt.ExpiredSignature:
            raise AuthenticationFailed('token过期了')
        except jwt.DecodeError:
            raise AuthenticationFailed('token解码失败')
        except jwt.InvalidTokenError:
            raise AuthenticationFailed('认证失败')
         #执行到这,说明token合法,payload可以使用、	
         user_id = payload.get('user_id')
         user = UserInfo.objects.filter(pk=user_id).first()
         #每次都要查数据库,效率不太好
         return (user,jwt_value)

2.RBAC的介绍和使用

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

#RBAC权限管理的模式,最适合公司内部的管理系统,不适合对外互联网用户的系统
	-用户:用户表
	-角色(部门):角色表(部门表)
	-权限:权限表
	-所有权都是存在权限表中,一条条的记录(发工资,招聘员工,开员工,发布新版本,开董事会)
	-权限是授予角色的(部门的)。一个个角色,就是一条条记录(开发角色,hr角色,股东角色)
	-用户:一个个用户是用户表中一条条记录,用户属于某个部门
	-三个表直接的关系
		-用户和角色关系:多对多,中间表
		-角色和权限关系:多对多,中间表
		-5张表
			-用户表
			-角色表
			-权限表
			-用户和角色关联表
			-角色和权限关联表
用户表
id 姓名
1 张三
2 李四
角色表
1 hr角色
2 股东角色
3 开发角色
权限表
id 角色名称
1 hr角色
2 股东角色
3 开发角色

​ 张三要有提交代码的权限

用户表和角色中间表
id   角色id 用户id
1	  3		1
--------------------------------
权限和角色的中间表
id		角色id	权限id
1		3			3

djangod的后台管理admin就自带了rbac的权限,通过auth模块实现的,比普通rbac更高级一些

-本来5张表

-django是6张表,用户和权限的多对多关系表(一个用户可以分配多个权限,一个权限可以给多个用户)

	-6张表
	  -用户表
	  -角色表
	  -权限表
	  -用户和角色关联表
	  -角色和权限关联表
	  -用户和权限的多对多关系表
-启用了admin和auth,这6张表就迁移进去了
	auth_user #用户表
	auth_group #角色,组,部门表
	auth_permission #权限表
	auth_user_groups #用户和角色中间表
	auth_group_permisssions #用户和权限的中间表
-之前很多公司写后台管理使用django,使用django的admin二次开发,不用写权限了,快速加功能即可

--体验django admin的rbac权限控制

ACL,RBAC,ABAC(PBAC,CBAC)权限控制的介绍

#ACL(Access Control List,访问控制列表)
	将用户或组等使用者直接与对象的权限对接
	-用户表,权限表,中间,给用户授权某些即可
	
#RBAC(Role-Based Access Control,基于角色的访问控制)

#RBAC+ACL django 公司用的比较多

#ABAC(Attribute-Based Access Control,基于属性的访问控制)

ABAC(Attribute-Based Access Control,基于策略的访问控制)

又称为PBAC(Policy-Based Access Control,基于策略的访问控制)

CBAC(Claims-Based Access Control,基于声明的访问控制)

传统的ACL、RBAC的架构是

{subject,action,object}, 

而ABAC的架构是

{subject,action,object,contextual}且为他们添加了parameter(参数)。
subject属性:比如用户的年龄、部门、角色、威望、积分等主题属性。
action属性:比如查看、读取、编辑、删除等行为属性。
object属性:比如银行账户、文章、评论等对象或资源属性。
contextual属性:比如时段、IP位置、天气等环境属性。
-------------------------------------------
eg;
权限表
id   权限名  
1     开除员工

id   权限名     属性
1    开除员工   女
1    开除员工   男

设计以上权限比较复杂,

CAsbin

Casbin 是一个强大的、高效的开源访问控制框架,其权限管理机制支持多种访问控制模型。方便我们快速的做权限控制、主流的权限都可以控制

介绍

Casbin 可以:
支持自定义请求的格式,默认的请求格式为{subject, object, action}。
具有访问控制模型model和策略policy两个核心概念。
支持RBAC中的多层角色继承,不止主体可以有角色,资源也可以具有角色。
支持内置的超级用户 例如:root 或 administrator。超级用户可以执行任何操作而无需显式的权限声明。
支持多种内置的操作符,如 keyMatch,方便对路径式的资源进行管理,如 /foo/bar 可以映射到 /foo*
-----------------------------------------------------------------------------------
Casbin 不能:
身份认证 authentication(即验证用户的用户名和密码),Casbin 只负责访问控制。应该有其他专门的组件负责身份认证,然后由 Casbin 进行访问控制,二者是相互配合的关系。
管理用户列表或角色列表。 Casbin 认为由项目自身来管理用户、角色列表更为合适, 用户通常有他们的密码,但是 Casbin 的设计思想并不是把它作为一个存储密码的容器。 而是存储RBAC方案中用户和角色之间的映射关系。

1665649333689

import casbin

e = casbin.Enforcer("./model.conf", "./policy.csv")

sub = "lqz"  # 想要访问资源的用户
obj = "book"  # 将要被访问的资源
act = "get"  # 用户对资源进行的操作


# 自己写acl的控制
# 当前用户id,去权限和用户表查询即可,有记录就是有权限

# 自己写rbac
# 当前用户id,找到他的角色,根据角色拿出权限,判断当前访问有没有


if e.enforce(sub, obj, act):
    # 允许alice读取data1
    print('有权限')
else:
    # 拒绝请求,抛出异常
    print('没有权限')

model.conf

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

policy.csv

p,alice,data1,read
p,bob,data2,write
p,lqz,book,get

3 后台管理simplui的介绍和使用

#django admin自带了权限控制,但是是前后端混合的,我们可以二次开发,开发出公司的自动化运维,自动化测试,人事管理系统,订单系统,样子不好看
---xadmin (不用了,过时了)
---simpleui (正红)

#基于drf +vue 自己写前后都安分离的权限管理
#go-vue-admin

#使用simpleui

settings.py

import time
SIMPLEUI_CONFIG = {
    'system_keep': False,
    'menu_display': ['我的首页', '图书管理','权限认证', '多级菜单测试', '动态菜单测试'],  # 开启排序和过滤功能, 不填此字段为默认排序和全部显示, 空列表[] 为全部不显示.
    'dynamic': True,  # 设置是否开启动态菜单, 默认为False. 如果开启, 则会在每次用户登陆时动态展示菜单内容
    'menus': [
        {
            'name': '我的首页',
            'icon': 'fas fa-code',
            'url': '/index/',

        },
        {
            'app': 'app01',
            'name': '图书管理',
            'icon': 'fas fa-code',
            'models': [
                {
                    'name': '用户',
                    'icon': 'fa fa-user',
                    'url': 'app01/userinfo/'
                },
                {
                    'name': '图书',
                    'icon': 'fa fa-user',
                    'url': 'app01/book/'
                },
                {
                    'name': '出版社',
                    'icon': 'fa fa-user',
                    'url': 'app01/publish/'
                },
            ]
        },
        {
            'app': 'auth',
            'name': '权限认证',
            'icon': 'fas fa-user-shield',
            'models': [{
                'name': '用户',
                'icon': 'fa fa-user',
                'url': 'auth/user/'
            }]
        },
        {
            # 自2021.02.01+ 支持多级菜单,models 为子菜单名
            'name': '多级菜单测试',
            'icon': 'fa fa-file',
            # 二级菜单
            'models': [
                {
                    'name': '百度',
                    'icon': 'far fa-surprise',
                    # 第三级菜单 ,
                    'models': [
                        {
                            'name': '爱奇艺',
                            'url': 'https://www.iqiyi.com/dianshiju/'
                            # 第四级就不支持了,element只支持了3级
                        },
                        {
                            'name': '百度问答',
                            'icon': 'far fa-surprise',
                            'url': 'https://zhidao.baidu.com/'
                        }
                    ]
                },
                {
                    'name': 'lqz',
                    'url': 'https://www.wezoz.com',
                    'icon': 'fab fa-github'
                }]
        },
        {
            'name': '动态菜单测试',
            'icon': 'fa fa-desktop',
            'models': [{
                'name': time.time(),
                'url': 'http://baidu.com',
                'icon': 'far fa-surprise'
            }]
        }]
}
SIMPLEUI_LOGIN_PARTICLES = False
SIMPLEUI_HOME_INFO = False

admin.py

from django.contrib import admin

# Register your models here.

from .models import *


@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    list_display = ('id', 'title', 'price')

    # 增加自定义按钮
    actions = ['make_copy', ]
    def make_copy(self, request, queryset):
        print('adsfasdf')
    make_copy.short_description = '自定义按钮'
    # # icon,参考element-ui icon与https://fontawesome.com
    make_copy.icon = 'fas fa-audio-description'
    # # 指定element-ui的按钮类型,参考https://element.eleme.cn/#/zh-CN/component/button
    make_copy.type = 'danger'
    make_copy.confirm = '你是否执意要点击这个按钮?'


admin.site.register(UserInfo)
admin.site.register(Publish)
posted @ 2022-10-13 19:23  名字长的像一只老山羊  阅读(37)  评论(0编辑  收藏  举报