为了账号安全,请及时绑定邮箱和手机立即绑定

基于角色的访问控制(RBAC)在Django中的实现方法

标签:
Python Django API

基于角色的访问控制 (RBAC) 是一种安全模型,它限制访问资源。在 Django 中,你可以通过利用内置的认证与授权框架来实现 RBAC,这允许你定义角色、分配权限并控制对应用程序特定部分的访问权限。本文提供了一个全面的指南说明,介绍如何在 Django 中使用自定义权限、组和中间件等来实现更复杂的 RBAC。

为什么使用基于角色的访问控制(RBAC)呢?

RBAC(基于角色的访问控制)可以帮助以可扩展和可维护的方式管理用户权限,特别是在需要为多个用户设置不同访问权限的应用程序中。它能帮助您:

  • 定义角色,并赋予它们特定的权限。
  • 将这些角色分配给用户。
  • 根据用户的角色,控制他们访问界面、模型等相关资源的权限。
Django认证系统中的重要概念

在深入了解之前,理解Django的认证系统非常重要:

  • 用户:代表一个单独的用户账户。
  • 权限:代表执行特定操作的能力,例如添加或删除一个资源。
  • :代表一个用户组。每个组可以拥有一套权限。
  • 角色:在角色基础访问控制的上下文中,角色通常被表示为具有特定权限的组。
第一步:搭建 Django 项目:

如果还没有的话,先创建一个新的Django项目和应用。

在终端中输入 `django-admin startproject myproject`  
在终端中输入 `cd myproject`  
在终端中输入 `python manage.py startapp myapp`

settings.py 文件的 INSTALLED_APPS 列表中添加你的新应用:

INSTALLED_APPS = [  
    ...  
    'myapp',  
    ...  
]

配置文件中,INSTALLED_APPS 列表中包含 'myapp',例如:

INSTALLED_APPS = [  
    ...  
    'myapp',  
    ...  
]
第2步:定义用户角色和权限

你可以为你的模型定义自定义权限。这些权限存储在数据库里,并可以分配给用户或用户组。

创建一个带有自定义权限设置的模型

我们可以在 myapp/models.py 文件中下面定义一个具有自定义权限的 Document 模型如下:

    from django.db import models  
    from django.contrib.auth.models import User  
    class Document(models.Model):  
        title = models.CharField(max_length=100)  
        content = models.TextField()  
        created_by = models.ForeignKey(User, on_delete=models.CASCADE)  
        class Meta:  
            permissions = [  
                ("can_publish_document", "可以发布文章"),  
                ("can_archive_document", "可以存档文章"),  
            ]  
        def __str__(self):  
            return self.title

首先,运行以下命令来创建和应用迁移:

# 创建一个新的迁移文件
python manage.py makemigrations

# 应用最新的迁移
python manage.py migrate
让我们使用`python manage.py makemigrations`命令来创建新的数据库迁移吧。
接下来,我们使用`python manage.py migrate`命令来应用这些迁移。
使用组来创建用户角色设置

你可以使用Django的Group模型来创建角色。每个组都可以有自己的特定权限。在myapp/management/commands/setup_roles.py

from django.core.management.base import BaseCommand  
from django.contrib.auth.models import Group, Permission  
from myapp.models import Document  
class Command(BaseCommand):  
    help = '创建用户角色并分配权限'  
    def handle(self, *args, **kwargs):  
        # 创建角色  
        editor_group, created = Group.objects.get_or_create(name='Editor')  # 创建 Editor 角色
        publisher_group, created = Group.objects.get_or_create(name='Publisher')  # 创建 Publisher 角色
        admin_group, created = Group.objects.get_or_create(name='Admin')  # 创建 Admin 角色
        # 分配权限  
        publish_permission = Permission.objects.get(codename='can_publish_document')  # 获取发布文档权限
        archive_permission = Permission.objects.get(codename='can_archive_document')  # 获取归档文档权限  

        # 将权限添加到各组  
        editor_group.permissions.add(publish_permission)  
        publisher_group.permissions.add(archive_permission)  
        admin_group.permissions.add(publish_permission, archive_permission)  
        self.stdout.write(self.style.SUCCESS('角色和权限已成功设置!'))

运行自定义命令来创建角色并分配权限,如下所示:

    python manage.py 设置角色权限
步骤 3:给用户分配角色:

你可以通过Django的管理界面或者编写代码将这些角色分配给用户。

通过管理界面给角色分配权限

  1. 进入Django管理界面。
  2. 导航到用户部分,选择一个用户。
  3. 向下滚动到“组”部分,找到,将用户添加到所需的组中(例如,编辑、发布、管理)。

程序化分配角色

    从 django.contrib.auth.models 导入 User, Group  

    # 将用户 'john_doe' 分配到 'Editor' 组
    user = User.objects.get(username='john_doe')  
    editor_group = Group.objects.get(name='Editor')  
    user.groups.add(editor_group)
步骤 4: 在视图中实施访问控制

Django 提供了多种在视图中实现访问控制的方法,包括装饰器和基于类的混入方法。

使用如下的**@permission_required**装饰器

@permission_required 装饰器会检查用户是否有特定权限,然后允许访问位于 myapp/views.py 的 view。

    from django.contrib.auth.decorators import permission_required  
    from django.shortcuts import render  
    from django.http import HttpResponse  

    @permission_required('myapp.can_publish_document', raise_exception=True)  
    def publish_document(request):  
        return HttpResponse("恭喜,您有权发布文档了。")

在类视图中使用**PermissionRequiredMixin**

在基于类的视图中,你可以使用位于myapp/views.py中的PermissionRequiredMixin类。

    导入 django.contrib.auth.mixins 中的 PermissionRequiredMixin  
    导入 django.views.generic 中的 TemplateView  

    class PublishDocumentView(PermissionRequiredMixin, TemplateView):  
        template_name = 'publish.html'  
        permission_required = 'myapp.can_publish_document'

该视图仅对拥有can_publish_document权限的用户可见。

第5步:创建全局访问控制的中间件

例如,您可以创建一个访问控制中间件来限制基于角色和权限的访问。访问控制中间件可以用来在整个应用程序中实施访问控制。例如在 myapp/middleware.py 文件中。

from django.shortcuts import redirect  
from django.contrib.auth.models import Group  

class 基于角色的访问控制中间类:  
    def __init__(self, get_response):  
        self.get_response = get_response  
    def __call__(self, request):  
        # 跳过中间件以处理管理员和超级用户  
        if request.user.is_authenticated and not request.user.is_staff and not request.user.is_superuser:  
            if 用户组中不存在名为 'Admin' 的组:  
                # 如果用户不在 'Admin' 组,则重定向到无权限页面  
                if 请求路径不以 '/no-permission' 开头:  
                    return redirect('/no-permission/')  
        response = self.get_response(request)  
        return response
settings.py 文件中加入 Middleware

要启用中间件,请将其添加到 settings.py 中的 MIDDLEWARE 列表或元组中。

    MIDDLEWARE = [  
        ...  
        'myapp.middleware.基于角色的访问控制中间件类',  
        ...  
    ]
第6步:自定义后台界面

Django的管理界面可以根据用户的权限自定义显示或隐藏特定模型或字段。

在管理界面中隐藏模型

myapp/admin.py 中覆盖 get_queryset 方法以限制对特定对象的访问。

    from django.contrib import admin  
    from .models import Document  

    class DocumentAdmin(admin.ModelAdmin):  
        def get_queryset(self, request):  
            qs = super().get_queryset(request)  
            if request.user.groups.filter(name='Editor').exists():  
                return qs.filter(created_by=request.user)  
            return qs  
    admin.site.register(Document, DocumentAdmin)
在后台界面隐藏字段信息

隐藏特定字段,可以在你的管理类中覆盖 get_fields 方法。

class DocumentAdmin(admin.ModelAdmin):  
    # 文档管理员类
    def get_fields(self, request, obj=None):  
        fields = super().get_fields(request, obj)  
        # 如果用户不是管理员组的成员,则从字段中移除'created_by'
        if not request.user.groups.filter(name='Admin').exists():  
            fields.remove('created_by')  
        return fields
第7步:测试与调试

验证用户权限和角色

  • 创建多个具有不同角色的测试用户。
  • 测试对各种视图的访问,确保只有应该访问的用户才能访问。
  • 通过用不同用户登录来测试中间件,验证他们是否如预期被重定向或允许访问。

调试小贴士

  • 在您的视图或模板中使用 request.user.has_perm('app_label.permission_codename') 动态验证权限。
  • 检查日志中的权限错误,并确保权限和组设置正确。

在 Django 中使用自定义权限、组和中间件实现基于角色的访问控制(RBAC),可以帮助你构建安全且易于维护的应用程序。按照本指南中的步骤,你可以创建符合特定需求的复杂访问控制体系。不论是简单的应用还是复杂的企业解决方案,RBAC 都提供了一种可扩展的方式来处理 Django 的用户权限和角色。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消