RBAC 是什么

RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联。

在 Django 中,权限就是用户对一个包含正则表达式 url 有没有访问的权利。

RBAC 的实现

在编写程序过程中,要注重弱耦合,所以在创建项目之初,应当将 RBAC 功能和逻辑功能分开来,创建不同的应用。

基于 RBAC 的权限管理最根本上需要对数据表进行更改。实现该方法需要五张表,用户表,角色表,权限表,用户与角色关系表,角色与权限关系表。

关于数据表的代码如下。

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

登录校验

对用户进行校验的前提是用户登录,并且用户登录信息浏览器要在其他页面当中依然能够取得,所以将用户 ID 存入 session 中。

在用户登录时除了存储用户 ID 信息外,还应存储用户的所有权限信息。

登录视图函数:

from django.shortcuts import render, HttpResponse
from rbac import models
import re
from rbac.service.permission import * # Create your views here.
def login(request):
if request.method == "POST":
username = request.POST["username"]
pwd = request.POST["pwd"]
user_obj = models.User.objects.filter(name=username, pwd=pwd).first() # 登录用户存在
if user_obj: # 将用户ID存入session
request.session["user_id"] = user_obj.pk # 查询当前登录用户的所有权限,注册到session中
initial_session(user_obj, request) return HttpResponse("登录成功!") return render(request, "login.html")

查询并注册用户权限信息到 session 的代码如下:

# /rbac/service/permission.py
def initial_session(user, request):
# 将用户权限列表存入session
# 取出登录用户的权限url并去重
# permissions = models.Role.objects.filter(user=user_obj).values("permissions__url").distinct()
permissions = user.roles.all().values("permissions__url").distinct()
permission_list = []
for item in permissions:
permission_list.append(item["permissions__url"]) request.session["permission_list"] = permission_list

在 session 中存储了用户 ID 信息后判断是否登录就很方便了:

# 校验是否登录
if not request.session.get("user_id"):
return redirect('/login/')

校验权限

前文中已经提到过,权限就是带正则表达式的 url ,对权限进行校验就是看当前 url 路径是否在用户权限列表中,如果在则用户有访问该 url 的权限。

其中,在判断当前路径是否在权限列表中时应该使用正则匹配并注意要完全匹配,不能简单的使用

元素 in 列表 这种简单判断。

# 当前路径
current_path = request.path_info # 校验权限
flag = False
permission_list = request.session.get("permission_list", [])
for permission in permission_list: # 保障url完全匹配
permission = "^%s$" % permission ret = re.match(permission, current_path)
if ret:
flag = True
break if not flag:
return HttpResponse("没有权限访问")

加入中间件

有了实现权限校验的代码之后,如果想要在各个 url 中都进行校验就需要在每个相应的视图函数中填上相应的代码,造成了代码冗余。

既然每个视图函数都需要进行校验,最好的办法就是使用中间件,项目启动后每次访问 url 都会自动走该中间件,从而进行了权限校验。

有关中间件的知识请参考:Django 中的中间件

使用中间件会发生一个问题:有些不需要校验的 url ,比如登录链接,注册链接,后台管理链接也都会进行校验从而报错,因此,需要对 url 设置一个白名单。

# 校验是否为白名单
valid_url_list = ["/login/", "/reg/", "/admin/.*"]
for item in valid_url_list:
ret = re.match(item, current_path)
if ret:
return None

中间件的完整代码:

# /rbac/service/rbac.py

from django.utils.deprecation import MiddlewareMixin
import re
from django.shortcuts import HttpResponse, redirect class ValidPermissionMiddleware(MiddlewareMixin): def process_request(self, request): # 当前路径
current_path = request.path_info # 校验是否为白名单
valid_url_list = ["/login/", "/reg/", "/admin/.*"]
for item in valid_url_list:
ret = re.match(item, current_path)
if ret:
return None # 校验是否登录
if not request.session.get("user_id"):
return redirect('/login/') # 校验权限
flag = False
permission_list = request.session.get("permission_list", [])
for permission in permission_list: # 保障url完全匹配
permission = "^%s$" % permission ret = re.match(permission, current_path)
if ret:
flag = True
break if not flag:
return HttpResponse("没有权限访问") return None

GitHub 地址:https://github.com/protea-ban/oldboy/tree/master/9day82/rbacDemo

基于中间件的RBAC权限控制的更多相关文章

  1. 基于SpringSecurity实现RBAC权限控制(待完善)

    Spring Security是一个为企业应用系统提供声明式的安全访问控制功能,减少为了企业应用系统安全控制而编写的大量重复代码. 认证: spring security的原理就是使用很多的拦截器对U ...

  2. 基于thinkphp的RBAC权限控制

    RBAC  Role-Based Access Control 权限控制在后台管理中是十分常见的,它的模型大体上是下面这张图的形式 我用的字段和上面不一样,图只是个示例 一个简易的权限控制模型只需要3 ...

  3. python RBAC权限控制模型扩展 基于JWT实现

    jwt,全称 json web token,是使用一定的加密规则生成的token串来保证登录状态.验证用户身份.做权限认证等工作 以往保存用户登录状态多用session实现,但是当服务涉及多台服务器分 ...

  4. vue基于d2-admin的RBAC权限管理解决方案

    前两篇关于vue权限路由文章的填坑,说了一堆理论,是时候操作一波了. vue权限路由实现方式总结 vue权限路由实现方式总结二 选择d2-admin是因为element-ui的相关开源项目里,d2-a ...

  5. yii2搭建完美后台并实现rbac权限控制实例教程

    1.安装yii2 未安装的请参考yii2史上最简单式安装教程,没有之一 或者参考yii2实战教程之详细安装步骤 已安装的请继续看下一步操作 2.配置数据库 2.1 配置数据库 修改common/con ...

  6. Kubernetes-16:一文详解ServiceAccount及RBAC权限控制

    一.ServiceAccount 1.ServiceAccount 介绍 首先Kubernetes中账户区分为:User Accounts(用户账户) 和 Service Accounts(服务账户) ...

  7. yii2 rbac权限控制详细操作步骤

    作者:白狼 出处:http://www.manks.top/article/yii2_rbac_description本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 ...

  8. yii2 rbac权限控制之菜单menu详细教程

    作者:白狼 出处:http://www.manks.top/article/yii2_rbac_menu本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...

  9. Struts2中基于Annotation的细粒度权限控制

    Struts2中基于Annotation的细粒度权限控制 2009-10-19 14:25:53|  分类: Struts2 |  标签: |字号大中小 订阅     权限控制是保护系统安全运行很重要 ...

随机推荐

  1. XML数据格式简介

    ---------------siwuxie095                             XML 简介     XML,即 可扩展标记语言(Extensible Markcup La ...

  2. 283. Move Zeroes把零放在最后面

    [抄题]: Given an array nums, write a function to move all 0's to the end of it while maintaining the r ...

  3. SqlServer——神奇代码1之Update

    说明:一个带有update的循环的代码.很简单,但是在QQ群里问了,应该说是很少有人注意这个问题,也就是很少有人真的理解SQL中的Update. 代码如下: if object_id('tempdb. ...

  4. Python pandas.DataFrame调整列顺序及修改index名

    1. 从字典创建DataFrame >>> import pandas >>> dict_a = {'],'mark_date':['2017-03-07','20 ...

  5. c语言学习笔记 多级else if 和switch case有什么区别

    ; ) { dosth(); } ) { dosth2(); } else if(opion==) { dosth3(); } else dosth4(); 如果给option的一个值是2的话,那么程 ...

  6. win32多线程 (一) 线程创建与结束等待

    #include "stdafx.h"#include <Windows.h>#include <iostream> using namespace std ...

  7. Requests接口测试(一)

    接口测试概念 接口测试是测试系统组件间接口的一种测试.接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点.测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关 ...

  8. HTML 5+CSS 3网页设计经典范例 (李俊民,黄盛奎) 随书光盘​

    <html 5+css 3网页设计经典范例(附cd光盘1张)>共分为18章,涵盖了html 5和css3中各方面的技术知识.主要内容包括html 5概述.html 5与html 4的区别. ...

  9. Js 正则获取Html元素

    var html = $("#summaryTemplate").html(); var imageMath = /<img [^<,>]*(?=target-t ...

  10. .Net 项目代码风格规范

    最近没啥时间自己状态也不是很好,公司的事情忙,自己也有一些事情要处理,所以好久没有写博客了.利用公司午休时间写一写,以下是参考了一些资料,整理出来,共勉之. 代码风格没有正确与否,重要的是整齐划一,清 ...