s11 day106-107 RBAC模块
一、登录 把权限存在session中
1. rbac models
from django.db import models class Permission(models.Model): """ 权限表 """ title = models.CharField(verbose_name='标题', max_length=32) url = models.CharField(verbose_name='含正则的URL', max_length=128) def __str__(self): return self.title class Role(models.Model): """ 角色 """ title = models.CharField(verbose_name='角色名称', max_length=32) permissions = models.ManyToManyField(verbose_name='拥有的所有权限', to='Permission', blank=True) def __str__(self): return self.title class UserInfo(models.Model): """ 用户表 """ name = models.CharField(verbose_name='用户名', max_length=32) password = models.CharField(verbose_name='密码', max_length=64) email = models.CharField(verbose_name='邮箱', max_length=32) roles = models.ManyToManyField(verbose_name='拥有的所有角色', to='Role', blank=True) def __str__(self): return self.name
2. web models
from django.db import models class Customer(models.Model): """ 客户表 """ name = models.CharField(verbose_name='姓名', max_length=32) age = models.CharField(verbose_name='年龄', max_length=32) email = models.EmailField(verbose_name='邮箱', max_length=32) company = models.CharField(verbose_name='公司', max_length=32) def __str__(self): return self.name class Meta: verbose_name_plural = "客户表" class Payment(models.Model): """ 付费记录 """ customer = models.ForeignKey(verbose_name='关联客户', to='Customer') money = models.IntegerField(verbose_name='付费金额') create_time = models.DateTimeField(verbose_name='付费时间', auto_now_add=True) class Meta: verbose_name_plural = "支付表"
#########权限相关########### PERMISSION_SESSION_KEY ="permission_list" VALID_URL=[ "^/login/$", "^/admin/.*", ]
from django.conf.urls import url from web.views import customer from web.views import payment from web.views import login urlpatterns = [ url(r'^customer/list/$', customer.customer_list), url(r'^customer/add/$', customer.customer_add), url(r'^customer/edit/(?P<cid>\d+)/$', customer.customer_edit), url(r'^customer/del/(?P<cid>\d+)/$', customer.customer_del), url(r'^customer/import/$', customer.customer_import), url(r'^customer/tpl/$', customer.customer_tpl), url(r'^payment/list/$', payment.payment_list), url(r'^payment/add/$', payment.payment_add), url(r'^payment/edit/(?P<pid>\d+)/$', payment.payment_edit), url(r'^payment/del/(?P<pid>\d+)/$', payment.payment_del), url(r"^login/",login.login) ]
from django.shortcuts import render,redirect from rbac import models # from luffy_permission.settings import PERMISSION_SESSION_KEY from django.conf import settings def login(request): if request.method == "GET": return render(request, 'login.html') #1. 获取提交的用户名和密码 user = request.POST.get("user") user = request.POST.get('user') pwd = request.POST.get("pwd") pwd = request.POST.get('pwd') #2.检验用户是否合法 obj = models.UserInfo.objects.filter(name=user, password=pwd).first() print(obj) if not obj: return render(request, 'login.html', {'msg': '用户名或密码错误'}) #3获取用户信息和权限信息写入session permission_list =obj.roles.filter(permissions__url__isnull = False).values('permissions__url').distinct() print(permission_list) for item in permission_list: print(item) request.session['user_info'] = {'id':obj.id,'name':obj.name} request.session[settings.PERMISSION_SESSION_KEY] = list(permission_list) return redirect('/customer/list/')
二、中间件
https://www.cnblogs.com/yuanchenqi/articles/9036467.html?tdsourcetag=s_pcqq_aiomsg (session知识点)
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import redirect,HttpResponse from luffy_permission import settings import re class RbacMiddleware(MiddlewareMixin): #权限控制的中间件 def process_request(self,request): #权限控制 #1. 获取当前请求url current_url =request.path_info #1.5 白名单处理 for reg in settings.VALID_URL: import re if re.match(reg,current_url): return None #2. 获取当前用户session所有权限 permission_list =request.session.get(settings.PERMISSION_SESSION_KEY) if not permission_list: return redirect("/login") #3.进行权限校验 print(current_url) print(permission_list) flag =False for item in permission_list: reg ="^%s$" % item.get("permissions__url") import re if re.match(reg,current_url): flag= True break if not flag: return HttpResponse("无权访问")
三 、为客户添加菜单 (二级菜单,一级菜单)
修改 models
class Permission(models.Model): """ 权限表 """ title = models.CharField(verbose_name='标题', max_length=32) url = models.CharField(verbose_name='含正则的URL', max_length=128) is_menu =models.BooleanField(verbose_name="是否可以作为菜单",default=False) icon =models.CharField(max_length=32,null=True,blank=True)
红色即为增加字段
略
四、生成组件.
1.设置一个初始化组件 ,将登陆后的权限信息和菜单信息放入session
from django.conf import settings def init_permission(request,user): """ 权限和菜单信息初始化,以后使用时,需要在登陆成功后调用该方法将权限和菜单信息放入session :param request: :param user: :return: """ # 3. 获取用户信息和权限信息写入session permission_queryset = user.roles.filter(permissions__url__isnull=False).values('permissions__url', 'permissions__is_menu', 'permissions__title', 'permissions__icon', ).distinct() menu_list = [] permission_list = [] for row in permission_queryset: permission_list.append({'permissions__url': row['permissions__url']}) if row['permissions__is_menu']: menu_list.append( {'title': row['permissions__title'], 'icon': row['permissions__icon'], 'url': row['permissions__url']}) request.session[settings.PERMISSION_SESSION_KEY] = permission_list request.session[settings.MENU_SESSION_KEY] = menu_list
2.登陆界面 ,留意红色字体,在调用权限组件
from django.shortcuts import render, redirect,HttpResponse from rbac import models from rbac.service.init_permission import init_permission from django.conf import settings def login(request): """ 用户登陆 :param request: :return: """ if request.method == 'GET': return render(request,'login.html') # 1. 获取提交的用户名和密码 user = request.POST.get('user') pwd = request.POST.get('pwd') # 2. 检验用户是否合法 obj = models.UserInfo.objects.filter(name=user,password=pwd).first() if not obj: return render(request, 'login.html',{'msg':'用户名或密码错误'}) request.session['user_info'] = {'id': obj.id, 'name': obj.name}
init_permission(request,obj)
return redirect('/student/') def student(request): return render(request,'student.html') def student_add(request): return render(request, 'student_add.html')
3.中间件组件的整合
from django.utils.deprecation import MiddlewareMixin from django.conf import settings from django.shortcuts import redirect,HttpResponse import re class RbacMiddleware(MiddlewareMixin): """ 权限控制的中间件 """ def process_request(self, request): """ 权限控制 :param request: :return: """ # 1. 获取当前请求URL current_url = request.path_info # 1.5 白名单处理 for reg in settings.VALID_URL: if re.match(reg,current_url): return None # 2. 获取当前用户session中所有的权限 permission_list = request.session.get(settings.PERMISSION_SESSION_KEY) if not permission_list: return redirect('/login/') # 3. 进行权限校验 flag = False for item in permission_list: reg = "^%s$" % item.get('permissions__url') if re.match(reg, current_url): flag = True break if not flag: return HttpResponse('无权访问')