美文网首页
rbac 角色权限控制

rbac 角色权限控制

作者: 鬼泣_89b6 | 来源:发表于2019-03-20 20:54 被阅读0次

    Role Based Access Control,基于角色的权限控制,用于计算机操作系统的安全性控制

    组件

    多个插件组合到一起的部件,用于实现一系列相关功能. 例如:form组件

    插件

    仅仅实现一个小功能 比如: 分页

    权限组件

    实现思路: 用户--->职位(角色)--->权限

    表结构设计

    1. 仅设计 权限表和用户表
    权限表 id url
    用户表 id name pwd .....
    [ 关系:多对多, 一个人要有多个权限( 查看,修改的权限 ),且一个权限可以被多个人使用 ]

    缺点:这种关系是繁琐的:一个职员的离职和入职,都需要删除和添加这个职员和权限的关系

    2.我们引入了角色的概念
    权限表 路由 标题
    用户表 姓名 密码
    角色表 名称
    [ 用户和角色是多对多的关系(要有兼职的概念) ; 权限和角色也是多对多的关系(BOSS和销售都要有 的权限),而BOSS不可能只有 的权限 ]

    一定要注意:权限的重叠

    流程
    1. 首先要记录每个用户的权限
      1. 登录注册功能
    2. 用户登录的时候,校验用户的路由
      1. 登录完成时,将用户的权限储存到session中,方便快速获取校验
      2. 登录完成后,要校验用户访问的路由,不能超出权限,所以我们要利用中间件,在访问之前完成校验
    3. 如果超出权限,抛出异常
    实践
    记录用户权限

    在 django 项目中创建并注册一个app

    简单示例:
    class Permission(models.Model):
        '''
        权限表
        '''
        url = models.CharField('权限', max_length=32)
        title = models.CharField('标题', max_length=32)
    
    
        def __str__(self):
            return self.title
    
    
    class Role(models.Model):
        '''
        角色表
        '''
        name = models.CharField('角色名称', max_length=32)
        permissions = models.ManyToManyField('Permission', verbose_name='角色拥有的权限', blank=True)
    
        def __str__(self):
            return self.name
    
    
    class User(models.Model):
        '''
        用户表
        '''
        name = models.CharField('用户名', max_length=32)
        pwd = models.CharField('密码', max_length=32)
        roles = models.ManyToManyField('Role', verbose_name='用户拥有的角色', blank=True)
    
        def __str__(self):
            return self.name
    

    我们进入应用下的 admin 文件中,用Django 提供的基于 web 的管理工具

    from django.contrib import admin
    from rbac import models  # 导入表结构
    
    class PermissionAdmin(admin.ModelAdmin):
        list_display = ['url', 'title', ]  # 显示字段
        list_editable = ['title', ]    # 修改字段
    
    # 创建的三个表
    admin.site.register(models.Permission, PermissionAdmin)
    admin.site.register(models.Role)
    admin.site.register(models.User)
    

    随后登录 admin 录入数据

    登录
    def login(request):
        '''登录'''
        msg = ''
        if request.method == 'POST':
            user = request.POST.get('username')
            pwd = request.POST.get('pwd')
            #  通过用户名和密码找到 用户对象
            user_obj= models.User.objects.filter(name=user,pwd=pwd).first()
            if user_obj:
                # 进行 ORM 操作
                通过对象找到角色,再通过角色找到权限.. '注意要去重:去除重复权限'
                ret = obj.roles.filter(permissions__url__isnull=False).values( xxx ).distinct()
                # 将权限列表保存到session中
                request.session[settings.PERMISSION_SESSION_KEY] = permission_list
                return redirect('customer_list')
            msg = '用户名或密码错误'
        return render(request,'login.html',{'msg':msg})
    
    校验

    在用户访问之前判断是否超出自己的权限,所以我们将权限的校验,放置到中间件中

    1. 获取当前访问的路由
    2. 设置白名单
    3. 判断是否登录,如果没有重定向到登录界面
    4. 免认证( 有一些页面,需要登录但是不需要校验,比如游客浏览的首页 )
    5. 获取当前用户的权限信息
    6. 循环校验
      1)对比成功 有权限 return
      2)不成功 没有权限 return HttpResponse(‘没有权限’)
      其中第3、4 步可以省略不写;还有注意中间件的注册
    from django.utils.deprecation import MiddlewareMixin  # 导入中间件
    from django.shortcuts import HttpResponse
    from django.conf import settings  # 将session的key保存到配置文件中,做常量,防止修改,而获取不到
    import re  # 进行正则匹配
    
    
    class Rbac_Middlewar(MiddlewareMixin):
        def process_request(self, request):
    
            # 获取当前的路由
            url = request.path_info
    
            # 白名单( 在 settings 中)
            for i in settings.WHITE_LIST:
                if re.match(i, url):
                    retur
    
            # 获取当前用户的权限
            Permission_list = request.session.get(settings.PERMISSION_SESSION_KEY)
    
            # 进行校验
            for i in Permission_list:
                if re.match('^{}$'.format(i["url"]), url):
                    return
    
            return HttpResponse('校验shibai')
    

    注意事项

    1. form表单的 input 框一定要有名字,否则你无法获取数据的内容
    2. ORM 的增删改查
    3. 在录入权限的路由时,注意输入含有正则的字符串

    比如 修改权限: 路由可以写作 /customer/edit/(\d+)/ , \d+ 可以表示被修改者的id

    1. 中间件的注册
    2. re模块的应用 math( 正则,字符串 )
    3. 当将 session 的键,作为常量写到 settings 配置文件中时,那么在模板中,无法获取到用户的权限,因为 模板语法仅支持点语法,没有 [ ] 的概念 ,所以我们可以通过 inclusion_tag 来返回自定义标签
     # 将权限列表保存到session中 
    request.session[settings.PERMISSION_SESSION_KEY] = permission_list
    
    # inclusion_tag 流程
    1.  创建一个
    2.  创建一个 自定义py文件
    3.  进行编写基础代码
    from django import template
    register = template.Library()
    
    
    @register.inclusion_tag('menu.html')
    def menu(request):
    
        menu_dic = request.session.get(settings.MENU_SESSION_KEY)
        print(menu_dic)
    
        return {'menu_dic': menu_dic}
    

    相关文章

      网友评论

          本文标题:rbac 角色权限控制

          本文链接:https://www.haomeiwen.com/subject/ajotvqtx.html