权限组件之rbac

rbac:基于角色的权限访问控制(Role-Based Access Control)。html

rbac的主要流程:给每一个角色赋予不一样的权限,是这个角色的员工都有这个角色的全部权限。一个角色能够有多我的员担任,一个员工能够担任多个角色(好比部门经理、业务员等)。当员工成功登录系统时,系统须要获取这个员工的多有权限,并放到一个列表里面。而后员工在访问每一个权限url时,系统须要进行判断该员工有没有这个权限进行这项操做。如何判断?就是循环这个员工的全部权限,看有没有对应的权限。这里用到了re模块里面的match方法。django

以下代码:session

# 须要先登录,拿到该员工的权限列表并去重
def
login(request): if request.method=="GET": return render(request,"login.html") else: user=request.POST.get("user") pwd=request.POST.get("pwd") user=UserInfo.objects.filter(name=user,pwd=pwd).first() if user: # 验证成功以后作什么? request.session["user_id"]=user.pk # 设置session # 当前登陆用户的全部权限, distinct()是去掉重复的权限 permission_info=user.roles.all().values("permissions__url","permissions__title").distinct() temp=[] # 该员工的所有权限url列表 for i in permission_info: temp.append(i["permissions__url"]) request.session["permission_list"]=temp # {"user_id":1,"permission_list":['/users/','/orders/']} return HttpResponse("登陆成功!") else: return redirect("/login/")

 登录成功以后,判断查看用户操做权限app

from django.shortcuts import HttpResponse

def users(request):
    # //users/
    current_path = request.path_info  # 拿到访问的路径
    permission_list = request.session.get("permission_list")  # 取session,从session表里面取到这个员工的全部权限 ['/order/', '/users/']
if not permission_list: # 用户没有登录,取不到权限列表
return HttpResponse("login.html") # /users/edit/3 为何要用正则,由于/users/edit/3 与/users/edit/(/d+)不能直接匹配 import re flag = False # 加上标志位 for permission_url in permission_list: ret = re.match(permission_url, current_path) # 用正则去匹配具体的路径,成功则返回对象, 不然返回None if ret: # 若是返回对象 flag = True break if not flag: return HttpResponse("没有访问权限") return HttpResponse("用户列表") # 有权限

 接下来经过中间件来实现这个功能url

再建立一个应用名字叫作rbac(固然也能够放到同一个应用里面),这个应用里面建立一个包service,包里建立一个名字为permission_li.py的文件。spa

from django.utils.deprecation import MiddlewareMixin

from django.shortcuts import  redirect,HttpResponse,render

class M1(MiddlewareMixin):
    def process_request(self,request):
        # //users/
        current_path = request.path_info  # 拿到访问的路径
        permission_list = request.session.get("permission_list")  # 从session表里面取到这个员工的全部权限 ['/order/', '/users/']
        # /users/edit/3  为何要用正则,由于/users/edit/3 与/users/edit/(/d+)不能直接匹配
        import re
        flag = False  # 加上标志位
        for permission_url in permission_list:
            ret = re.match(permission_url, current_path)  # 用正则去匹配具体的路径,成功则返回对象, 不然返回None
            if ret:  # 若是返回对象
                flag = True
                break
        if not flag:
            return HttpResponse("没有访问权限")

settings.py里面code

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'rbac.service.permission_li.M1',  # 加在这里
]

接下来的问题就是,加上中间件以后,登录页面也没有权限访问了。csrf

咱们添加白名单,登录、注册和admin页面加里便可。htm

from django.utils.deprecation import MiddlewareMixin

from django.shortcuts import  redirect,HttpResponse,render

class M1(MiddlewareMixin):
    def process_request(self,request):
        pass

        #/admin/login/?next=/admin/
        current_path = request.path_info

        valid_url_menu=["/login/","/reg/","/admin/.*"]
        import re
        for valid_url in valid_url_menu:
            ret=re.match(valid_url,current_path)
            if ret:
                return None

        permission_list = request.session.get("permission_list")
        if not permission_list:
            return redirect("/login/")
        # /users/edit/3
        import re
        flag = False
        for permission_url in permission_list:
            ret = re.match(permission_url, current_path)
            if ret:
                flag = True
                break
        if not flag:
            return HttpResponse("没有权限")
相关文章
相关标签/搜索