zoukankan      html  css  js  c++  java
  • rbac

    一、rbac

    权限组件
       1 项目与应用
            一个项目,可以有多个应用
            一个应用,可以在多个项目下
            前提:应用是组件!!
    
       2 什么是权限?
         一个包含正则表达式url就是一个权限
    
         who    what   how   ---------->True  or  Flase
    
         UserInfor
             id
             name
             pwd
             permission=models.manytomany(Permission)  多对多
    
        id    name   pwd
        1    egon   123
        2    alex   456
        3    A      111
        4    B      222
        5    C      333
        6    D      444
    
    
         Permission
            id
            url=.....
              title=....
    
            id       url            title
            1     "/users/"         "查看用户"
            2     "/users/add/"     "添加用户"
            3    "/customer/add"   "添加客户"
    
         UserInfor_permission
    
            id
            user_id
            permission_id
    
    
            id    user_id   permission_id
             1       1           1
             2       1           2
             3       2           2
    
             4       3           1
             5       3           2
             6       3           3
    
             7       4           1
             8       4           2
             9       4           3
    
    
             10       5           1
             11       5           2
             12       5           3
    
    
             13       6           1
             14       6           2
             15       6           3
    
    
             16       7           1
             17       7           2
             18       7           3
    
    
        示例:登录人:egon
              访问url:http://127.0.0.1:8000/users/
    
              def users(request):
                 user_id=request.session.get("user_id")
    
                 obj=UserInfor.objects.filter(pk=user_id).first()
                 obj.permission.all().valuelist("url")   # 基于对象的跨表查询
    
                 return HttpResponse("users.....")
    
    
    这样做 是否 有问题?
    假设:10人 。。。 应该,不同的角色有不同的权限!
    
    不要给人定权限,
    应该给角色定权限
    rbac  正确的 见 版本2
    ------------------------------------------------------------
    
        # 版本2:
    
        UserInfor
             id
             name
             pwd
             roles = manytomany() 多对多
    
            name   pwd
            egon   123
            alex   456
            alex   456
            alex   456
    
        Role
           id
           title=.......
           permissions = manytomany() 多对多
    
             id   title
             1    销售员
    
        UserInfor2Role
    
           id     user_id    role_id
            1        1          1
    
        Permission
            id
            url=.....
              title=....
    
        id       url            title
        1     "/users/"         "查看用户"
        2     "/users/add/"     "添加用户"
         3    "/customer/add"    "添加客户"
    
    
        Role2Permission
    
        id  role_id   permission_id
         1      1           1
         2      1           2
         3      1           3
    
    
    rbac(role-based access control)
    
    app01 做的是项目相关的逻辑内容
    rbac 制作权限相关的内容
    
    关于rbac:  # 要把他它成组件
    
        (1) 创建表关系:
            class User(models.Model):
                name=models.CharField(max_length=32)
                pwd=models.CharField(max_length=32)
                roles=models.ManyToManyField(to="Role")
    
                def __str__(self): return self.name
    
            class Role(models.Model):
                title=models.CharField(max_length=32)
                permissions=models.ManyToManyField(to="Permission")
    
                def __str__(self): return self.title
    
            class Permission(models.Model):
                title=models.CharField(max_length=32)
                url=models.CharField(max_length=32)
    
                def __str__(self):return self.title
    
        (2) 基于admin录入数据
    
    
        (3) 登录校验:
    
            if 登录成功:
    
                查询当前登录用户的权列表注册到session中
    
        (4) 校验权限(中间件的应用)
            class ValidPermission(MiddlewareMixin):
    
                def process_request(self,request):
    
                    # 当前访问路径
                    current_path = request.path_info
    
                    # 检查是否属于白名单
                    valid_url_list=["/login/","/reg/","/admin/.*"]
    
                    for valid_url in valid_url_list:
                        ret=re.match(valid_url,current_path)
                        if ret:
                            return None
    
    
                    # 校验是否登录
    
                    user_id=request.session.get("user_id")
    
                    if not user_id:
                        return redirect("/login/")
    
    
                    # 校验权限
                    permission_list = request.session.get("permission_list",[])  # ['/users/', '/users/add', '/users/delete/(\d+)', 'users/edit/(\d+)']
    
    
                    flag = False
                    for permission in permission_list:
    
                        permission = "^%s$" % permission
    
                        ret = re.match(permission, current_path)
                        if ret:
                            flag = True
                            break
                    if not flag:
                        return HttpResponse("没有访问权限!")
    
                    return None
    笔记

    rbac(role-based access control)

    基于角色的权限访问控制 

    二、数据库

    1.新建一个应用:
    startapp rbac

    INSTALLED_APPS = [
    ...
    'app01.apps.App01Config',
    'rbac.apps.RbacConfig',
    ]

    makemigrations
    migrate

    models.py

    from django.db import models
    
    class User(models.Model):
        name = models.CharField(max_length=32)
        pwd = models.CharField(max_length=32)
        roles = models.ManyToManyField(to='Role')
    
        def __str__(self):
            return self.name
    
    class Role(models.Model):
        title = models.CharField(max_length=32)
        permission = models.ManyToManyField(to='Permission')
    
        def __str__(self):
            return self.title
    
    class Permission(models.Model):
        title = models.CharField(max_length=32)
        url = models.CharField(max_length=32)
    
        def __str__(self):
            return self.title

    三、admin

    1.前提
    createsuperuser
    (yuan yuan1234)

    admin.py

    from django.contrib import admin
    
    # Register your models here.
    
    from .models import *
    
    admin.site.register(User)
    admin.site.register(Role)
    admin.site.register(Permission)

    四、登录验证 (session permission_list)  

    1.在session中注册用户ID
    request.session['user_id'] = user.pk

    2.初始化 permission_list 并注册到session 中
    initial_session(user,request)

    rbac/service/permission.py
    def initial_session(user, request):
        permission = user.roles.all().values('permission__url').distinct()
    
        # print(permission)
        # 去重后的  所有权限!! 将权限 存在 session 中!!
        # <QuerySet [{'permission__url': '/users/'}, {'permission__url': '/users/add'}]>
    
        permission_list = []
        for item in permission:
            permission_list.append(item['permission__url'])
    
        print(permission_list)
        # ['/users/', '/users/add']
    
        request.session['permission_list'] = permission_list

    注意点:

    permission = user.roles.all().values('permission__url').distinct()
    1.values:      
    temp = []
    for role in user.roles.all(): # < QuerySet[ < Role: 保洁 >, < Role: 销售 >] >
    temp.append({
    'title':role.title
    'permission__url': role.permission__url.all()
    })
    return temp

    2.values 不会去重!!
    <QuerySet [{'title': '保洁', 'permission__url': '/users/'},
    {'title': '销售', 'permission__url': '/users/'},
    {'title': '销售', 'permission__url': '/users/add'}]>

    views.py
    def login(request):
        if request.method == 'POST':
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
    
            user = User.objects.filter(name=user,pwd=pwd).first()
            if user:
                # 在session中注册用户ID
                request.session['user_id'] = user.pk
    
                # 初始化 permission_list 并注册到session 中
                initial_session(user,request)
    
                return HttpResponse('登录成功')
    
        return render(request,'login.html')

    五、基于中间件的权限校验

    MIDDLEWARE = [
    ...
    'django.middleware.csrf.CsrfViewMiddleware',
    ...
    'rbac.service.rbac.ValidPermission',
    ]

    注意点:

    1.白名单,不需要任何权限的url
    valid_url_list = ['/login/', '/reg/', '/admin/.*']
    for valid_url in valid_url_list:
    ret = re.match(valid_url, current_path)
    if ret:
    return

    正则匹配

    2.校验是否登录,
    user_id = request.session.get('user_id')
    if not user_id:
    return redirect('/login/')

    3.校验权限(^ $ / 正则)
    permission_list = request.session.get('permission_list',[])

    flag = False
    for permission in permission_list:
    # ['/users/', '/users/add/', '/users/edit/(\d+)/', '/users/delete/(\d+)/']
    # 需要 ^ $ 限定!!
    permission = "^%s$" % permission

    # 正则
    ret = re.match(permission, current_path)
    if ret:
    flag = True
    break

    if not flag:
    return HttpResponse('无访问权限!')

    rbac/service/rbac.py
    # -*- coding:utf-8 -*-
    from django.shortcuts import HttpResponse, render, redirect
    from django.utils.deprecation import MiddlewareMixin
    import re
    
    class ValidPermission(MiddlewareMixin):
    
        def process_request(self,request):
    
            current_path = request.path_info
    
            # 白名单,不需要任何权限的url
            valid_url_list = ['/login/', '/reg/', '/admin/.*']
    
            for valid_url in valid_url_list:
                ret = re.match(valid_url, current_path)
                if ret:
                    return
    
            # 校验是否登录
            user_id = request.session.get('user_id')
            if not user_id:
                return redirect('/login/')
    
            # 校验权限
            permission_list = request.session.get('permission_list',[])
    
            flag = False
            for permission in permission_list:
                # ['/users/', '/users/add/', '/users/edit/(\d+)/', '/users/delete/(\d+)/']
                # 需要 ^ $ 限定!!
                permission = "^%s$" % permission
    
                ret = re.match(permission, current_path)
                if ret:
                    flag = True
                    break
    
            if not flag:
                return HttpResponse('无访问权限!')
  • 相关阅读:
    python2.7_1.4_将IPV4地址转换成不同的格式
    大型网站问题的解决方案
    大型网站的标准
    SCP服务实现Linux交互
    SCP服务实现Linux交互
    使用Linux系统中的SSH服务
    向php文件中添加php.ini文件
    让apache与mysql随着系统自动启动
    为apache与mysql创建快捷方式
    安装PHP软件
  • 原文地址:https://www.cnblogs.com/alice-bj/p/9169109.html
Copyright © 2011-2022 走看看