django之权限
权限的含义
web权限,包含正则的url
关于权限的理解和模型设计可参考:https://www.cnblogs.com/myindex/p/9116177.html
权限值应用创建
创建如图权限应用
权限之表关系设计(rbac模式-role based access control)
在model设计如下表结构并注册(并使用之前设计好的stark组件,注册到stark里面生成增删改查四张表)
from django.db import models # Create your models here. class User(models.Model): #用户表 username = models.CharField(max_length=32) pwd = models.CharField(max_length=32) roles = models.ManyToManyField('Role') #一个用户可以对应多个角色 def __str__(self): return self.username class Role(models.Model): #角色表 title = models.CharField(max_length=32) permissions = models.ManyToManyField('Permission') #一个角色可以对应多多种权限 def __str__(self): return self.title class Permission(models.Model): #权限表 title = models.CharField(max_length=32) url = models.CharField(max_length=128) def __str__(self): return self.title
创建如下应用(这个应用是为了我么待会儿用户去访问这个模型的的一些相关操作进行权限设计的)
设计其模型表,并注册到stark组件中生成增删改查四个页面
from django.db import models # Create your models here. class Customer(models.Model): #客户表 name = models.CharField(max_length=32) def __str__(self): return self.name class Order(models.Model): #订单表 order_id = models.CharField(max_length=32) def __str__(self): return self.order_id
权限之录入权限
如图,在第一个表设计号之后就可以如下添加权限
并如下录入权限 (自己设计)
给role添加关联的user
权限之查看注入当前登陆用户的权限
在app01的views函数中设计挡路函数
from django.shortcuts import render, HttpResponse, redirect from rbac.models import User # Create your views here. def login(request): if request.method == 'POST': user = request.POST.get('user') pwd = request.POST.get('pwd') user_obj = User.objects.filter(username=user, pwd=pwd).first() if user_obj: # 录入用户灯枯信息 request.session['user_id'] = user_obj.pk # 获取当前登录对象的所有权限 # (1)获取当前登录对象的所有角色,(2)获取角色权限 # permissions = user_obj.roles.all().values('permissions__url').distinct() #去重 # permission_list = [] # for permission in permissions: #拿到每一个字典的值(url)加入列表 # permission_list.append(permission['permissions__url']) # request.session['permission_list'] = permission_list # print(permission_list)
from rbac.service.permissions import permission_init permission_init(request,user_obj) return redirect('/index/') else: return redirect('/login.html/') else: return render(request, 'login.html')
这样我们便能取到用户的相关权限列表url,但是这个必须走登录这个函数,用户不登录也能访问啊?
我们设计一个中间件(请求必须走的),并注册
注册:
中间件:
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import render, redirect, HttpResponse import re class PermissionMiddleware(MiddlewareMixin): def process_request(self, request): """ 请求访问控制 一旦此次请求不在当前登录用户权限列表中,即forbidden """ # 获取当前请求路径 current_path = request.path print('current_path', current_path) # 1 放行白名单 white_list = ['/login/', '/admin/*', '/index/','/favicon.ico'] for path in white_list: if re.search(path, current_path): return None # 2 判断是否登录 user_id = request.session.get('user_id') if not user_id: return redirect('/login/') # 3 校验权限 校验当前访问路径是否在当前用户权限表中 # 3.1获取当前用用户权限表 permission_list = request.session.get('permission_list') print('permission_list', permission_list) # 3.2 校验当前登录用户权限表 正则匹配 for path in permission_list: path = '^%s$' % path if re.search(path, current_path): return None return HttpResponse('你没有访问权限')
中间件的校验这个功能又是很多应用都是可以使用的,我们呢就把他提取到一个文件中,需要在导入
permissions.py
def permission_init(request,user_obj): permissions = user_obj.roles.all().values('permissions__url').distinct() # 去重 permission_list = [] for permission in permissions: # 拿到每一个字典的值(url)加入列表 permission_list.append(permission['permissions__url']) request.session['permission_list'] = permission_list