django的RBAC介绍1

1、django的权限管理叫做RBAC

我们在百度上查看RBAC的概念如下

基于角色的权限访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注。在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。角色与角色的关系可以建立起来以囊括更广泛的客观情况。

2、下面我们先来看下django的rbac该如何设计

首先我们要设计三张表,表1为用户表,表2为角色表,表3为权限表,用户表关联角色表,角色表关联权限表,用户属于某个角色,而某个角色可以包含一些权限,同样一个用户可以属于多个角色,而一个角色同样可以包含多个权限,下面我们看下我们的model中的设计

from django.db import models

# Create your models here.

class Userinfo(models.Model):
    username = models.CharField(max_length=64)
    uerpwd = models.CharField(max_length=64)
    roles = models.ManyToManyField(to="Role")

    def __str__(self):
        return self.username
    class Meta:
        verbose_name = "用户表"
        verbose_name_plural = verbose_name

class Role(models.Model):
    title = models.CharField(max_length=64)
    pers = models.ManyToManyField(to="per")

    def __str__(self):
        return self.title
    class Meta:
        verbose_name="角色表"
        verbose_name_plural = verbose_name

class per(models.Model):
    title = models.CharField(max_length=64)
    url = models.CharField(max_length=128)

    def __str__(self):
        return self.title
    class Meta:
        verbose_name = "权限表"

  

设计好表结构后,我们先往表中写数据,我们先看用户表中的数据

我们点开看下具体某个用户的角色信息

我们可以看到,用户test1有2个角色,角色1是CEO,角色2是销售角色

然后我们在看角色表

我们在看下某个角色具体的权限,我们这里定义权限就是操作库的权限,比如增删改查四个权限

我们可以看到CEO有4个权限,分别是增删改查4个权限

最后我们在看下权限表,通过权限表,我们就可以看到一共有4个权限

我们看下具体的权限的表内容,我们可以看到具体的权限就是一条url

从上面的数据库的设计,我们可以知道,控制url的访问就是控制权限

3、最后我们进入具体的代码的逻辑控制

我们思路是这样的,因为从上面我们可以看到,如果某个用户没有某个权限,那么我们就控制这个用户是否能访问这条url就可以了,那么我们怎么做呢?

思路1、可以写在视图函数中

思路2、可以写在视图函数的装饰器中

思路3、可以写在中间件中

我们可以考虑一下,哪种最好呢?当然是第三种最好,因为每个请求都会发一个request,如果这个用户没有这个方位这个url的权限,那么我们直接在中间件就把这个请求拦截就可以了,不需要让这个请求在往后走,占用我们的资源,您说对吗?

那么下面就看下具体的代码

用户首先要登陆,那么登陆后,我们就需要把用户信息存储到session中,同样,我们也需要从数据库中获取我这个用户的权限信息,然后存储到session中,以后我们就可以从session拿到我这次访问的用户和我这个用户所拥有的权限,以后我们中间件函数就从session中获取这次访问的用户信息

视图函数中的代码如下

def login(request):
    if request.method == "GET":
        return render(request, "rbac_login.html")
    else:
        name = request.POST.get("name")
        pwd = request.POST.get("pwd")

        if rbacmodels.Userinfo.objects.filter(username=name,uerpwd=pwd).exists():
            userobj = rbacmodels.Userinfo.objects.get(username=name)

            request.session["userid"] = userobj.id

            # print(userobj.roles.all())
            obj = userobj.roles.all().values_list("pers__url").distinct()
            per_list = []
            for i in obj:
                per_list.append(i[0])
            request.session["per_list"] = per_list
            print(per_list)
            # request.session.flush()
            # print(dir(request.session))
            # print("=" * 120)
            return redirect("/user/")
        else:
            return render(request, "rbac_login.html")

  

下面我们在看下中间件函数是怎么实现的

我们首先要搞一个白名单,如果url在这个白名单里,则可以直接访问,不用走后面的控制逻辑,因为比如login这类的url,你必须要放通他,如果你连login函数也拦截了,那么可以都无法登陆了

其次我们还要搞一个判断用户是否登陆的判断,如果客户没有登陆,则让他返回到登陆界面

最后,我们在写权限的控制逻辑,判断当前访问的url是否在权限列表中,如果在则通过,如果不在,则直接retrun回去,就达到了权限控制的需求了

from django.utils.deprecation import MiddlewareMixin
import re
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
from django.shortcuts import reverse

class My_rbac_mid(MiddlewareMixin):

    def process_request(self,request):
        current_path = request.path_info

        # 校验白名单

        white_list = ["/login/","/admin/.*"]
        for wh in white_list:
            wh = "^" + wh + "$"
            res = re.match(wh,current_path)
            if res:
                return None

        # 校验登陆
        if request.session.get("userid"):
            pass
        else:
            return redirect("/login/")

        # 校验权限
        per_list = request.session.get("per_list",[])
        flag = False
        if per_list:
            for per in per_list:
                if flag == False:
                    obj = "^" + per + "$"
                    res = re.match(obj,current_path)
                    if res:
                        flag = True
                        break
                    else:
                        continue
        if flag == False:
            return HttpResponse("无权限访问")

  

4、最后我们看下html代码是如何渲染的,我们的目的是如果该用户没有这个权限,则连按钮都不让他看到

{% extends ‘rbac_base.html‘ %}

{% block con %}

    <h4>用户列表</h4>

    {% if "/user/add/" in per_list %}
        <a href="/user/add/" class="btn btn-primary">添加用户</a>
    {% endif %}

    <table class="table table-bordered table-striped">
        <thead>
              <tr>
                   <th>序号</th>
                   <th>姓名</th>
                   <th>角色</th>
                   <th>操作</th>
              </tr>
        </thead>
       <tbody>
            {% for user in user_list %}
            <tr>
                 <td>{{ forloop.counter }}</td>
                 <td>{{ user.username }}</td>
                 <td>
                     {% for role in user.roles.all %}
                        {% if forloop.last %}
                            {{ role.title }}
                         {% else %}
                            {{ role.title }}|
                         {% endif %}
                     {% endfor %}

                 </td>

                 <td>
                     {%  if "/user/del/(\d+)" in per_list %}
                        <a href="/user/del/{{ user.id }}"><button type="button" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span>&nbsp删除</button></a>
                     {% endif %}

                    {%  if "/user/edit/(\d+)" in per_list %}
                        <a href="/user/edit/{{ user.id }}"><button type="button" class="btn btn-success"><span class="glyphicon glyphicon-pencil"></span>&nbsp编辑</button></a>
                    {% endif %}
                 </td>
            </tr>
            {% endfor %}

       </tbody>
    </table>

{% endblock %}

  

我将逻辑控制的地方截图出来,大家重点看下

如果有增加权限,则显示增加按钮

如果有删除权限,则显示删除按钮

如果有 编辑权限,则显示i编辑按钮

原文地址:https://www.cnblogs.com/bainianminguo/p/10010160.html

时间: 2024-10-14 10:56:28

django的RBAC介绍1的相关文章

Django的Rbac的介绍2

上一篇博客我们记录了一下Django中使用Rbac,但是上一篇博客中的方法有一点不好,就是,因为我要在html文件中控制:如果用户有某个权限,则显示这个权限所代表的按钮,但是我现在只有1张表的增删改查,但是如果我有多张表呢,我难道要每张表都写一次类似下面的代码吗? {% if "/user/del/(\d+)" in per_list %} <a href="/user/del/{{ user.id }}"><button type="b

Django - Django框架 简单介绍

Django框架 简单介绍 本文地址: http://blog.csdn.net/caroline_wendy/article/details/29172271 1. 介绍 Django是一个开放源码的Web应用框架, 由Python写成. 採用了MVC的软件设计模式, 即模型M, 视图V和控制器C. 它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的站点的, 并于2005年7月在BSD许可证下公布. 这套框架是以比利时的吉普赛爵士吉他手Django Reinhardt来命名的.

Django中ORM介绍和字段及字段参数

https://www.cnblogs.com/liwenzhou/p/8688919.html Django中ORM介绍和字段及字段参数 Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中. ORM在业务逻辑层和数据库

nginx+uwsgi部署django的简单介绍

1.安装django  环境ubuntu:sudo pip install django 2.新建一个django项目 命令:django-admin.py startproject  wlwebsite1 启动项目:python manage.py runserver 0.0.0.0:8000 浏览器查看,如下显示即正常 3.django项目有了,现在安装uwsgi 环境ubuntu:sudo pip install uwsgi 安装成功后看uwsgi版本:uwsgi --version ws

Django中ORM介绍和字段及其参数

ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中. ORM在业务逻辑层和数据库层之间充当了桥梁的作用. ORM的由来 字母‘O’起源于“对象”(Object),'R'代表“关系”(Relational). 几乎所有的软件开发过程中都会涉及到对象和关系数据库.在用户层面和业务逻辑层

django框架基本介绍

一.mvc和mtv 1.mvc介绍 MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller),具有耦合性低.重用性高.生命周期成本低等优点. 想要更详细的了解MVC模式? >> 点我 Django框架的设计模式借鉴了MVC框架的思想,也是分成三部分,来降低各个部分之间的耦合性. Django框架的不同之处在于它拆分的三部分为:Model(模型).Template(模

Django中ORM介绍

目录 一 ORM介绍 1.1 ORM 概念 1.2 ORM的由来 1.3 ORM的优势 1.4 ORM的劣势 1.5 ORM总结 二 Django中的ORM 2.1 Django使用MySQL数据库 2.2 Model 2.3 快速入门 一 ORM介绍 1.1 ORM 概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动

python学习第五六十七天:创建Django与项目介绍

主流web框架总结 a socket b 路由关系 c 模板字符串替换(模板语言) 主流web框架 djange a用别人的 b自己写 c自己写 flask a用别人的 b自己写 c用别人的(jinja2) tornado a自己写 b自己写 c自己写 创建Django 1 Django模块安装 2 创建Django项目 django-admin startproject 项目名 3 mange.py 管理我的django项目 4 (1) 启动django--python3 -manage.py

Django 中 form 介绍

目录 Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确.如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.. Django form组件就实现了上面所述的功能. 总结一下,其实form组件的主要功能如下: 生成页面可用的HTML标签 对用户提交的数据进行校验 保留上次输入内容 普通方式手写注册功能