首页 > 解决方案 > 如何构建 Django 权限以拥有多个类别的权限组?

问题描述

我想使用 Django Rest Framework 为 API 提供多层权限,我怎样才能最好地实现这一点?

具体来说,我拥有的三类授权是:

后两个类别同样适用于所有模型,不需要为每个模型提供单独的权限会很好。

想法1:

为从标准 django auth 组继承的每个类别创建一个模型。将这些作为代理组执行,在我的代码中逻辑上有所不同,但尽可能与标准授权一致。然后使用 django-guardian 启用对象级权限。

想法2:

对角色使用标准组,并根据这些组分配模型级别的权限。对于对象级权限,在 Django Rest Framework 中编写自定义权限类来检查用户的对象级权限。

标签: djangodjango-rest-frameworkdjango-permissions

解决方案


我最近设计了这样一个架构,所以我想到的第一件事是这样的:

  1. 角色:您可以通过添加角色级别的选项来覆盖 django 的内置 AbstractUser 类,例如:
# models.py
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    """Custom user model with an extra type field"""
    SUPER_USER = 1
    OTHER_ROLE = 2
    SOME_OTHER_ROLE = 3

    USER_TYPE_CHOICES = (
        (SUPER_USER, 'Super user'),
        (OTHER_ROLE, 'Other role'),
        (SOME_OTHER_ROLE, 'Some other role'),
    )

    user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES)

# -------------------------------------------------------------------------

# Don't forget to set this User model as your default model
# settings.py
AUTH_USER_MODEL = 'my_app.User'

  1. You can get use of django's built-in Group model and put a ForeignKey to your Team models and do object-level permission manually.
# models.py
from django.contrib.auth.models import Group
from django.db import models

def Team(models.Model):
    group = models.ForeignKey(Group, on_delete=models.CASCADE)

# -------------------------------------------------------------------------

# You can do object-level permission per group by
# ...
if team.group in permitted_groups:
    # permission granted
    pass
else:
    # permission not granted
    pass
# ...
  1. You can define a Tag model and add as ManyToManyField to your sensitive information model. Similar to the second solution above, you can manually do object-level permission during runtime by relying on your current information's tags.

推荐阅读