1、权限组件rbac

1、什么是权限

1 项目与应用

2 什么是权限?

一个包含正则表达式url就是一个权限

who what how ---------->True or Flase

 

2、版本: 用户--》角色--》权限

rbac权限+中间件

rbac权限+中间件
    UserInfor
     
         name       
         pwd
         roles
        
        
        
        name   pwd    
        egon   123            
        alex   456    
        alex   456    
        alex   456    
        alex   456    
        alex   456    
        alex   456    
        alex   456    
        alex   456    
        
            
    Role
       
       title=.......       
       permissions=......
       
         id   title
         1   销售员
       
    
    UserInfor2Role

       id     user_id    role_id    
        1        1          1

        
    Permission
     
        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
         
         
         
    3  rbac(role-based access control) 
     
     
rbac权限+中间件

 3.数据表的初步设计

from django.db import models

# Create your models here.

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)      #权限的url

    action=models.CharField(max_length=32,default="")  #权限操作(add,list,edit,delete)
    group=models.ForeignKey("PermissionGroup",default=1,on_delete=models.CASCADE)
    def __str__(self):
        return self.title

class PermissionGroup(models.Model):
    title=models.CharField(max_length=32)

    def __str__(self):
        return self.title
 

1)项目目录结构

rbac权限+中间件

2)数据库表

rbac权限+中间件rbac权限+中间件

 3)admin添加数据

创建超级用户 alex

rbac权限+中间件rbac权限+中间件rbac权限+中间件rbac权限+中间件rbac权限+中间件rbac权限+中间件rbac权限+中间件

 

 注册数据表

from django.contrib import admin

# Register your models here.


from .models import *

admin.site.register(User)
admin.site.register(Role)
admin.site.register(Permission)

 4、登录验证

1、session中注册用户,权限

1.在session中注册用户ID
request.session['user_id'] = user.pk
2.初始化 permission_list 并注册到session 中
initial_session(user,request)

 

        if 登录成功:
            user=User.objects.filter(name=user,pwd=pwd).first()
            只要这个user对象存在
            initial_session(user,request)通过传入登录的user对象和request
            可以把当前登录用户的权限列表和user_id注册到session中。
        else:
            redirect("/login/")

    ** 把设置session单独做成一个函数接口降低耦合,只需要传入登录用户的对象。
        def initial_session(user,request):
        permissions = user.roles.all().values("permissions__url").distinct()
        #通过登录用户对象查找到所有的角色对象QuerySet,然后跨表到权限表取到URL,做一个去重
 <QuerySet [{'permissions__url': '/users/'}, {'permissions__url': '/users/add'},  {'permissions__url': '/users/delete/(\\d+)'}]>

注意点:

permission = user.roles.all().values('permission__url').distinct()
 #将这些权限取到对应的URL并且添加到列表中,设置在session中。
 permission_list = []
 for item in permissions:
     permission_list.append(item["permissions__url"])
 print(permission_list)
 request.session["permission_list"] = permission_list

2、解耦

 

 rbac权限+中间件rbac权限+中间件

 
def initial_session(request,user):
    permissions = user.roles.all().values("permissions__url").distinct()

    permission_list = []
    for item in permissions:
        permission_list.append(item['permissions__url'])

    print(permission_list)  # ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)']

    request.session["permission_list"] = permission_list


    """
    values :

    for role in user.roles.all():   # <QuerySet [<Role: 保洁>, <Role: 销售>]>
        temp.append({
        "title":role.title,
        "permissions_url":role.permissions.all()
        })

    # <QuerySet [{'title': '保洁', 'permissions__url': '/users/'},
    # {'title': '销售', 'permissions__url': '/users/'},
    # {'title': '销售', 'permissions__url': '/users/add'}]>

    """
 

 rbac权限+中间件rbac权限+中间件

 

 

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

1、middleware如何构造

 设置中添加中间件"rbac.service.rbac.ValidPermissionMiddleware"

 

rbac权限+中间件

 

2、正则匹配

 
from django.test import TestCase

# Create your tests here.

# 当前path 如何与 paths匹配
# 不能用in   /users/delete/9
# 正则匹配


li = ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)']

c_path = "/users/delete/9"

import re

flag = False

for permission in li:
    permission = "^%s$" % permission
    ret = re.match(permission, c_path)
    if ret:
        flag = True
        break

if flag:
    print("success")

# ret = re.match("/users/", "/users/delete/9")
ret = re.match("^/users/$", "/users/delete/9")
print(ret)
 

rbac权限+中间件

3、构建中间件

 rbac权限+中间件rbac权限+中间件

        import re
        from django.utils.deprecation import MiddlewareMixin
        from django.shortcuts import  HttpResponse,redirect

        class ValidPermissionMiddleWare(MiddlewareMixin):
            def process_request(self,request):
                # 当前访问路径
                current_path = request.path_info

                #1层校验 检查是否属于白名单
                valid_url_list=["/login/","/reg/","/admin/.*"]
                for valid_url in valid_url_list:
                    ret=re.match(valid_url,current_path)
                    if ret:
                        return None

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

                # 3层校验校验权限
                permission_list = request.session.get("permission_list",[])   
                #['/users/', '/users/add', '/users/delete/(\\d+)', 'users/edit/(\\d+)']

                flag = False
                for permission in permission_list:
                    #此处做一个RE拼接,不然容易匹配失败
                    permission = "^%s$" % permission
                    ret = re.match(permission, current_path)
                    if ret:
                        flag = True
                        break
                if not flag:
                    return HttpResponse("没有访问权限!")
                    #在此处就直接告诉用户没有权限,不再进入视图。
                return None

 4、views视图,url

rbac权限+中间件

 

url.py

 
from django.contrib import admin
from django.urls import path,re_path

from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'^users/$',views.users),
    re_path(r'^users/add/$',views.add_user),
    re_path(r'^roles/$',views.roles),
    re_path(r'^login/$',views.login),
]
 

 

views

 
from django.shortcuts import render, HttpResponse

# Create your views here.

from rbac.models import *


def users(request):
    user_list = User.objects.all()

    return render(request, "users.html", locals())


def add_user(request):

    """
    permission_list = request.session["permission_list"]  # # ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)']
    current_path = request.path_info

    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 HttpResponse('add user')


def roles(request):
    role_list = Role.objects.all()
    print(role_list)

    # 方式2 middleware


    """
    # 方式1
    permission_list = request.session["permission_list"]  # # ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)']
    current_path = request.path_info

    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 render(request, "roles.html", locals())


from rbac.service.perssions import *
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中注册用户
            request.session['user_id'] = user.pk


            ############# 在session中注册权限list

            # 查询当前登录用户的所有角色
            # ret = user.roles.all()
            # print(ret)   # <QuerySet [<Role: 保洁>, <Role: 销售>]>

            # 查询当前登录用户的所有权限

            initial_session(request, user)

            return HttpResponse("登录成功")


    return render(request, 'login.html', locals())
 

注意点

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('无访问权限!')
 

4、总结:关于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权限+中间件

 

 

1、权限组件rbac

1、什么是权限

1 项目与应用

2 什么是权限?

一个包含正则表达式url就是一个权限

who what how ---------->True or Flase

 

2、版本: 用户--》角色--》权限

rbac权限+中间件

rbac权限+中间件
    UserInfor
     
         name       
         pwd
         roles
        
        
        
        name   pwd    
        egon   123            
        alex   456    
        alex   456    
        alex   456    
        alex   456    
        alex   456    
        alex   456    
        alex   456    
        alex   456    
        
            
    Role
       
       title=.......       
       permissions=......
       
         id   title
         1   销售员
       
    
    UserInfor2Role

       id     user_id    role_id    
        1        1          1

        
    Permission
     
        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
         
         
         
    3  rbac(role-based access control) 
     
     
rbac权限+中间件

 3.数据表的初步设计

from django.db import models

# Create your models here.

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)      #权限的url

    action=models.CharField(max_length=32,default="")  #权限操作(add,list,edit,delete)
    group=models.ForeignKey("PermissionGroup",default=1,on_delete=models.CASCADE)
    def __str__(self):
        return self.title

class PermissionGroup(models.Model):
    title=models.CharField(max_length=32)

    def __str__(self):
        return self.title
 

1)项目目录结构

rbac权限+中间件

2)数据库表

rbac权限+中间件rbac权限+中间件

 3)admin添加数据

创建超级用户 alex

rbac权限+中间件rbac权限+中间件rbac权限+中间件rbac权限+中间件rbac权限+中间件rbac权限+中间件rbac权限+中间件

 

 注册数据表

from django.contrib import admin

# Register your models here.


from .models import *

admin.site.register(User)
admin.site.register(Role)
admin.site.register(Permission)

 4、登录验证

1、session中注册用户,权限

1.在session中注册用户ID
request.session['user_id'] = user.pk
2.初始化 permission_list 并注册到session 中
initial_session(user,request)

 

        if 登录成功:
            user=User.objects.filter(name=user,pwd=pwd).first()
            只要这个user对象存在
            initial_session(user,request)通过传入登录的user对象和request
            可以把当前登录用户的权限列表和user_id注册到session中。
        else:
            redirect("/login/")

    ** 把设置session单独做成一个函数接口降低耦合,只需要传入登录用户的对象。
        def initial_session(user,request):
        permissions = user.roles.all().values("permissions__url").distinct()
        #通过登录用户对象查找到所有的角色对象QuerySet,然后跨表到权限表取到URL,做一个去重
 <QuerySet [{'permissions__url': '/users/'}, {'permissions__url': '/users/add'},  {'permissions__url': '/users/delete/(\\d+)'}]>

注意点:

permission = user.roles.all().values('permission__url').distinct()
 #将这些权限取到对应的URL并且添加到列表中,设置在session中。
 permission_list = []
 for item in permissions:
     permission_list.append(item["permissions__url"])
 print(permission_list)
 request.session["permission_list"] = permission_list

2、解耦

 

 rbac权限+中间件rbac权限+中间件

 
def initial_session(request,user):
    permissions = user.roles.all().values("permissions__url").distinct()

    permission_list = []
    for item in permissions:
        permission_list.append(item['permissions__url'])

    print(permission_list)  # ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)']

    request.session["permission_list"] = permission_list


    """
    values :

    for role in user.roles.all():   # <QuerySet [<Role: 保洁>, <Role: 销售>]>
        temp.append({
        "title":role.title,
        "permissions_url":role.permissions.all()
        })

    # <QuerySet [{'title': '保洁', 'permissions__url': '/users/'},
    # {'title': '销售', 'permissions__url': '/users/'},
    # {'title': '销售', 'permissions__url': '/users/add'}]>

    """
 

 rbac权限+中间件rbac权限+中间件

 

 

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

1、middleware如何构造

 设置中添加中间件"rbac.service.rbac.ValidPermissionMiddleware"

 

rbac权限+中间件

 

2、正则匹配

 
from django.test import TestCase

# Create your tests here.

# 当前path 如何与 paths匹配
# 不能用in   /users/delete/9
# 正则匹配


li = ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)']

c_path = "/users/delete/9"

import re

flag = False

for permission in li:
    permission = "^%s$" % permission
    ret = re.match(permission, c_path)
    if ret:
        flag = True
        break

if flag:
    print("success")

# ret = re.match("/users/", "/users/delete/9")
ret = re.match("^/users/$", "/users/delete/9")
print(ret)
 

rbac权限+中间件

3、构建中间件

 rbac权限+中间件rbac权限+中间件

        import re
        from django.utils.deprecation import MiddlewareMixin
        from django.shortcuts import  HttpResponse,redirect

        class ValidPermissionMiddleWare(MiddlewareMixin):
            def process_request(self,request):
                # 当前访问路径
                current_path = request.path_info

                #1层校验 检查是否属于白名单
                valid_url_list=["/login/","/reg/","/admin/.*"]
                for valid_url in valid_url_list:
                    ret=re.match(valid_url,current_path)
                    if ret:
                        return None

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

                # 3层校验校验权限
                permission_list = request.session.get("permission_list",[])   
                #['/users/', '/users/add', '/users/delete/(\\d+)', 'users/edit/(\\d+)']

                flag = False
                for permission in permission_list:
                    #此处做一个RE拼接,不然容易匹配失败
                    permission = "^%s$" % permission
                    ret = re.match(permission, current_path)
                    if ret:
                        flag = True
                        break
                if not flag:
                    return HttpResponse("没有访问权限!")
                    #在此处就直接告诉用户没有权限,不再进入视图。
                return None

 4、views视图,url

rbac权限+中间件

 

url.py

 
from django.contrib import admin
from django.urls import path,re_path

from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'^users/$',views.users),
    re_path(r'^users/add/$',views.add_user),
    re_path(r'^roles/$',views.roles),
    re_path(r'^login/$',views.login),
]
 

 

views

 
from django.shortcuts import render, HttpResponse

# Create your views here.

from rbac.models import *


def users(request):
    user_list = User.objects.all()

    return render(request, "users.html", locals())


def add_user(request):

    """
    permission_list = request.session["permission_list"]  # # ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)']
    current_path = request.path_info

    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 HttpResponse('add user')


def roles(request):
    role_list = Role.objects.all()
    print(role_list)

    # 方式2 middleware


    """
    # 方式1
    permission_list = request.session["permission_list"]  # # ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)']
    current_path = request.path_info

    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 render(request, "roles.html", locals())


from rbac.service.perssions import *
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中注册用户
            request.session['user_id'] = user.pk


            ############# 在session中注册权限list

            # 查询当前登录用户的所有角色
            # ret = user.roles.all()
            # print(ret)   # <QuerySet [<Role: 保洁>, <Role: 销售>]>

            # 查询当前登录用户的所有权限

            initial_session(request, user)

            return HttpResponse("登录成功")


    return render(request, 'login.html', locals())
 

注意点

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('无访问权限!')
 

4、总结:关于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权限+中间件

 

 

分类:

技术点:

相关文章: