权限
根据URL进行限制用户可以访问的资源
项目与应用的关系
项目可包含多个应用
应用可包含在多个项目中
RBAC:基于权限的管理系统
项目
先创建一个Django项目
Model
from django.db import models class UserInfo(models.Model): name = models.CharField(max_length=32) pwd = models.CharField(max_length=32,default=123) email = models.EmailField() 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): url = models.CharField(max_length=32) title = models.CharField(max_length=32) def __str__(self): return self.title
前端模板
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <form action="/login/" method="post"> {% csrf_token %} <p>用户名<input type="text" name="user"></p> <p>密码<input type="password" name="pwd"></p> <p><input type="submit" value="登录"></p> </form> </body> </html>
URL
urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^login/‘, views.login), url(r‘^users/‘, views.user_list), url(r‘^orders/‘, views.role_list), ]
后端
from django.shortcuts import render, HttpResponse, redirect from rbac.models import UserInfo, Role, Permission def login(request): if request.method == "GET": return render(request, "login.html") if request.method == "POST": username = request.POST.get("user") pwd = request.POST.get("pwd") user = UserInfo.objects.filter(name=username, pwd=pwd).first() if user: request.session["user_id"] = user.pk permission_list = user.roles.all().values("permissions__url", "permissions__title").distinct() temp = [] for per_url in permission_list: temp.append(per_url["permissions__url"]) request.session["permissions_list"] = temp print(temp) return HttpResponse("OK") else: return redirect(‘/login/‘) def user_list(request): return HttpResponse("用户列表") def role_list(request): return HttpResponse("订单列表")
后端有很多的视图函数,如果编写装饰器进行判断用户是否有权限访问,有三十个视图函数,就需要在三十个视图函数上添加装饰器函数,因此装饰器的方法不太妥当,取而代之的是中间件的方法
from django.utils.deprecation import MiddlewareMixin #注意 from django.shortcuts import render,redirect, HttpResponse from rbac.models import UserInfo import re #注意 class M1(MiddlewareMixin): def process_request(self,request): current_path = request.path_info permission_list = request.session.get("permissions_list") print(permission_list) valid_menu = ["/login/","/reg/","/admin/.*"] # 如果不设置白名单,admin的url也会被判为无权限,而且不需要验证的函数少, 先设置白名单, # 如果用户输入的url在白名单中就会return None for valid_url in valid_menu: ret = re.match(valid_url,current_path) #注意 if ret: return None if not permission_list: return None Flage = False for per_url in permission_list: re_macth = re.match(per_url,current_path) if re_macth: Flage = True break if not Flage: return HttpResponse("无权限")
创建中间价的步骤
1、在项目中创建一个应用application,自己命名至于为什么?这是前面提到的:“一个应用可以包含在多个项目中”,方便以后的使用
2、在项目中创建一个文件夹service,
3、在service 中创建一个py文件
4、创建一个类,必须继承 MiddlewareMixin
5、该类中必须有一个函数,process_request
做好以上步骤,效果如下图