Django_rbac_demo 权限控制组件框架模型
2024-09-22 07:52:39
rbac 权限控制组件
- 基于角色的权限控制
- 本质每个权限即为一个 URL
项目组件结构
表结构
Role (title, permission) -(ManyToManyField)- User (name, pwd, roles)
|
(ManyToManyField)
|
Permission (title, url)
实际生成表 及 测试数据
Django_rbac/ rbca/models.py
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) def __str__(self):return self.title
核心代码部分
Django_rbac/ rbac/service/permission.py
用于获取当前用户的权限信息
"""
为了解耦,将处理权限的代码保存在组件里面
""" def initial_session(user,request):
# 查看当前用户的所有的权限
# 因为会有values 的原理会导致有重复需要去重
ret = user.roles.all().values("permissions__url").distinct()
permission_list = []
# 将所有的权限保存在一个列表里面,稍微处理下数据便于操作
for i in ret:
permission_list.append(i["permissions__url"])
# 把用户的用户权限保存在 session 里面
request.session["permission_list"] = permission_list
Django_rbac/rbac/service/rbca.py
基于当前用户的权限信息对来访请求进行逻辑判断筛选返回结果
为了不冗余代码写在中间件中,对每一次的请求都做计算
因中间件的工作机制导致所有的请求都被计算,需要对特殊的 URL 进行特殊处理
import re
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, redirect
"""
写在中间件里面可以完全避免每次都要重复校验的问题
在请求来的时候进行校验,因此要写在 process_request 方法里面
""" class ValidPermission(MiddlewareMixin):
def process_request(self,request):
# 当前访问路径
current_path = request.path_info
"""
检查是否属于白名单
admin 的内部流程
不允许一上来就访问首页,必须要跳转到 登陆页面
http://127.0.0.1:8000/admin/login/?next=/admin/
第二次跳转到登录页面的请求如果没有被定义可通过就会被拦截
无法只使用 admin 为过滤选项
不能用 in 单纯的判断,还是要用到正则处理
需要放过所有 admin 开头的 url
"""
valid_url_list = ["/login/","/reg/","/admin/.*"]
for valid_url in valid_url_list:
ret = re.match(valid_url,current_path)
if ret:
# 中间件 return None 表示这个中间件已经执行完毕
return None """
校验是否登录
对于没有登陆的用户返回报错应该是让他去登陆
"""
user_id = request.session.get("user_id")
if not user_id:
return redirect("/login/") """
校验权限
在编辑,以及删除页面的时候 url 不是固定的,
会有内含的参数,因此权限列表里面不能仅仅是写死的url
也不能再单纯的用 in 来判断。还是要靠正则来处理
将权限列表里面的权限信息用 正则表达式来保存
然后对访问页面进行验证是否可以通过来处理
"""
permission_list = request.session.get("permission_list",[])
flag = False
for permission in permission_list:
permission = f"^{permission}$"
ret = re.match(permission, current_path)
if ret:
flag = True
break
if not flag:
return HttpResponse("没有访问权限! ")
return None
不要忘记注册在 Django_rbac\Django_rbac\settings.py 里面
其他app 引用使用
Django_rbac/app01/views.py
from django.shortcuts import render,HttpResponse
import re
# Create your views here.
from rbac.models import *
from rbac.service.perssions import initial_session def users(request):
user_list=User.objects.all()
return render(request,"users.html",locals()) def add_user(request):
permission_list = request.session["permission_list"]
return HttpResponse("add user.....") def roles(request):
role_list=Role.objects.all()
return render(request,"roles.html",locals()) 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:
# 把用户的id 保存在 session 里面
request.session["user_id"] = user.pk
# 查询当前用户的所有的权限
initial_session(user,request)
return HttpResponse("登录成功!")
return render(request, "login.html",locals())
测试页面代码
这个就比较随意了,看个结果而已。
Django_rbac\templates\login.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body> <h4>登录页面</h4> <form action="" method="post">
{% csrf_token %} 用户名:<input type="text" name="user">
密码:<input type="password" name="pwd">
<input type="submit">
</form> </body>
</html>
Django_rbac\templates\roles.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body> <h4>角色列表</h4>
<ul>
{% for role in role_list %}
<p>{{ role }}</p>
{% endfor %} </ul> </body>
</html>
Django_rbac\templates\users.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body> <h4>用户列表</h4>
<ul>
{% for user in user_list %}
<p>{{ user }}</p>
{% endfor %} </ul> </body>
</html>
最新文章
- linux Mysql 安装及配置
- winform快速开发平台->;让有限的资源创造无限的价值!
- 移动UI设计
- SharePoint远程调试CSS
- .NET编译的目标平台(AnyCPU,x86,x64)
- iOS 调出storyboard里面起始Controller的箭头
- win7设置防火墙允许Ping与telnet
- Java多线程——<;七>;多线程的异常捕捉
- [ASP.NET MVC] 利用动态注入HTML的方式来设计复杂页面
- sql management studio 附加mdf文件出错的解决办法
- 多数据库下activiti的流程定义缓存问题
- hdu2413(二分+二分匹配)
- trait
- 学习笔记︱深度学习以及R中并行算法的应用(GPU)
- Pushgateway 介绍
- Flagr 配置说明
- ubuntu mysql Access denied for user root@localhost
- 通过 sass-resources-loader 全局注册 Sass/Less 变量
- Android组件系列----Intent详解
- 3、zookeeper 集群模式搭建
热门文章
- Android Studio Termanal打不开,提示java.io.IOEXception:couldn&#39;t create PTY
- js 条件判断
- SQL SELECT DISTINCT 语句
- Keepalived脑裂
- git 命令添加整个文件夹以及文件夹下的内容
- KAPTCHA验证码使用步骤
- Log4j配置文件详解及实例
- vue 对象提供的属性功能、通过axio请求数据(2)
- vue-router query 传对象需要JSON.stringify()转化
- 使用springMVC时的web.xml配置文件