django2.0记录 基于RBAC的权限访问限制中间件

django2.0记录 基于RBAC的权限访问限制中间件

背景介绍

python3环境,前后端不分离,前端使用bootstrap2框架,后端使用django2.0框架,只是个人日常记录,仅供参考

目的

RBAC权限访问限制,有权限访问,无权限禁止访问

实现思路

请求接口前从session中获取用户的访问权限,判断请求方式及请求地址是否在权限范围中,扫描权限白名单,判断是否可以请求

后端实现代码

from django.conf import settings
from django.shortcuts import HttpResponse, redirect
import re


class MiddlewareMixin(object):
    def __init__(self, get_response=None):
        self.get_response = get_response
        super(MiddlewareMixin, self).__init__()

    def __call__(self, request):
        response = None
        if hasattr(self, 'process_request'):
            response = self.process_request(request)
        if not response:
            response = self.get_response(request)
        if hasattr(self, 'process_response'):
            response = self.process_response(request, response)
        return response


class RbacMiddleware(MiddlewareMixin):
    """
    检查用户的url请求是否是其权限范围内
    """

    def process_request(self, request):
        request_url = request.path_info
        method = request.method
        permission_url = request.session.get(settings.SESSION_PERMISSION_REQUEST_KEY)
        print('访问url', method, request_url)
        print('权限--', permission_url)
        # 如果请求url在白名单,放行
        for url in settings.SAFE_URL:
            if re.match(url, request_url):
                print('白名单通过')
                return None

        # 如果未取到permission_url, 重定向至登录
        # Login必须设置白名单
        if not permission_url:
            return redirect(settings.LOGIN_URL)

        # 循环permission_url,作为正则,匹配用户request_url
        # 正则应该进行一些限定,以处理:/user/ -- /user/add/匹配成功的情况
        flag = False
        url_list = []
        for request in permission_url:
            url = request.get('request_url')
            url_list.append(url)
            request_method = request.get('request_method')
            url_pattern = settings.REGEX_URL.format(url=request_url)
            if re.match(url_pattern, url) and method == request_method:
                flag = True
                break
        if flag:
            print('可以访问')
            return None
        else:
            print('不可访问')
            # 如果是调试模式,显示可访问url
            if settings.DEBUG:
                info = '<br/>' + ('<br/>'.join(url_list))
                return HttpResponse('无权限,请尝试访问以下地址:%s' % info)
            else:
                return HttpResponse('无权限访问')
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RBAC(Role-Based Access Control)是一种基于角色的访问控制,它将权限授予角色,然后将角色授予用户。在Django中,可以使用django-guardian或django-rules等第三方来实现RBAC权限管理,也可以自己编写代码实现。 下面是一个基于Django自己编写的简单RBAC权限管理系统的实现过程: 1. 定义权限模型 在Django中,可以通过定义模型来表示权限。例如,可以定义一个Permission模型,用来表示系统中的所有权限: ``` from django.db import models class Permission(models.Model): name = models.CharField(max_length=255, unique=True) codename = models.CharField(max_length=100, unique=True) ``` 其中name字段表示权限的名称,codename字段表示权限的代码名称。 2. 定义角色模型 同样地,可以定义一个Role模型,用来表示系统中的所有角色: ``` from django.db import models class Role(models.Model): name = models.CharField(max_length=255, unique=True) permissions = models.ManyToManyField('Permission') ``` 其中name字段表示角色的名称,permissions字段表示角色拥有的权限。 3. 定义用户模型 可以使用Django自带的User模型或者自己定义一个用户模型。在用户模型中,可以添加一个roles字段,用来表示用户所拥有的角色: ``` from django.contrib.auth.models import AbstractUser from django.db import models class User(AbstractUser): roles = models.ManyToManyField('Role') ``` 4. 编写权限检查装饰器 在Django中,可以使用装饰器来检查用户是否拥有某个权限。下面是一个简单的权限检查装饰器的实现: ``` from functools import wraps from django.http import HttpResponseForbidden def permission_required(perm): def decorator(view_func): @wraps(view_func) def _wrapped_view(request, *args, **kwargs): if not request.user.has_perm(perm): return HttpResponseForbidden() return view_func(request, *args, **kwargs) return _wrapped_view return decorator ``` 在上面的代码中,permission_required装饰器接受一个权限codename作为参数,返回一个装饰器函数。这个装饰器函数接受一个视图函数作为参数,返回一个新的视图函数。新的视图函数在执行前会检查用户是否拥有该权限,如果没有则返回403禁止访问状态码。 5. 在视图函数中使用权限检查装饰器 在需要进行权限检查的视图函数上加上permission_required装饰器即可: ``` @permission_required('app.view_model') def my_view(request): # do something ``` 在上面的代码中,my_view函数需要拥有view_model权限才能访问。 6. 编写角色管理视图 可以编写一个简单的角色管理视图,用来管理系统中的角色和权限: ``` from django.shortcuts import render from .models import Role, Permission def role_list(request): roles = Role.objects.all() return render(request, 'role_list.html', {'roles': roles}) def role_detail(request, role_id): role = Role.objects.get(id=role_id) permissions = Permission.objects.all() return render(request, 'role_detail.html', {'role': role, 'permissions': permissions}) ``` 在上面的代码中,role_list函数返回所有角色的列表,role_detail函数返回指定角色的详细信息和所有权限的列表。 7. 编写用户角色管理视图 可以编写一个简单的用户角色管理视图,用来管理用户和角色的关联关系: ``` from django.shortcuts import render from django.contrib.auth.models import User from .models import Role def user_list(request): users = User.objects.all() return render(request, 'user_list.html', {'users': users}) def user_detail(request, user_id): user = User.objects.get(id=user_id) roles = Role.objects.all() return render(request, 'user_detail.html', {'user': user, 'roles': roles}) ``` 在上面的代码中,user_list函数返回所有用户的列表,user_detail函数返回指定用户的详细信息和所有角色的列表。 8. 编写用户角色管理视图的表单处理函数 可以编写一个简单的表单处理函数,用来处理用户和角色的关联关系: ``` from django.shortcuts import redirect from django.contrib.auth.models import User from .models import Role def assign_role(request, user_id): if request.method == 'POST': user = User.objects.get(id=user_id) role_ids = request.POST.getlist('roles') roles = Role.objects.filter(id__in=role_ids) user.roles.set(roles) return redirect('user_detail', user_id=user_id) ``` 在上面的代码中,assign_role函数接受一个用户ID作为参数,从POST请求中获取选中的角色ID,将这些角色和用户关联起来,然后重定向到用户详细信息页面。 9. 编写角色管理视图的表单处理函数 可以编写一个简单的表单处理函数,用来处理角色和权限的关联关系: ``` from django.shortcuts import redirect from .models import Role, Permission def assign_permission(request, role_id): if request.method == 'POST': role = Role.objects.get(id=role_id) permission_ids = request.POST.getlist('permissions') permissions = Permission.objects.filter(id__in=permission_ids) role.permissions.set(permissions) return redirect('role_detail', role_id=role_id) ``` 在上面的代码中,assign_permission函数接受一个角色ID作为参数,从POST请求中获取选中的权限ID,将这些权限和角色关联起来,然后重定向到角色详细信息页面。 10. 编写模板 最后,可以编写一些简单的模板来渲染上述视图函数返回的数据。 例如,可以编写role_list.html模板来渲染角色列表: ``` <ul> {% for role in roles %} <li><a href="{% url 'role_detail' role.id %}">{{ role.name }}</a></li> {% endfor %} </ul> ``` 可以编写role_detail.html模板来渲染角色详细信息和权限列表: ``` <h1>{{ role.name }}</h1> <h2>Permissions</h2> <form method="post" action="{% url 'assign_permission' role.id %}"> {% csrf_token %} {% for permission in permissions %} <label> <input type="checkbox" name="permissions" value="{{ permission.id }}" {% if permission in role.permissions.all %}checked{% endif %}> {{ permission.name }} </label> {% endfor %} <button type="submit">Save</button> </form> ``` 可以编写user_list.html模板来渲染用户列表: ``` <ul> {% for user in users %} <li><a href="{% url 'user_detail' user.id %}">{{ user.username }}</a></li> {% endfor %} </ul> ``` 可以编写user_detail.html模板来渲染用户详细信息和角色列表: ``` <h1>{{ user.username }}</h1> <h2>Roles</h2> <form method="post" action="{% url 'assign_role' user.id %}"> {% csrf_token %} {% for role in roles %} <label> <input type="checkbox" name="roles" value="{{ role.id }}" {% if role in user.roles.all %}checked{% endif %}> {{ role.name }} </label> {% endfor %} <button type="submit">Save</button> </form> ``` 至此,一个简单的RBAC权限管理系统就完成了。当然,实际应用中可能需要更复杂的权限管理需求,可以根据具体情况进行扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值