Django - 如何在 DRF 中创建自定义权限以限制用户进行 API 未经授权的调用?

Django - How do I create custom permissions in DRF to restrict users from making API calls that they are not authorised to?

我正在开发一个使用 DRF 作为后端并使用 ReactJS 作为前端的网络应用程序。我的网络应用程序有来自不同销售部门的用户,我想限制权限,以便只有来自销售部门 A 的用户才能看到在销售部门 A 下标记的销售项目,如果用户尝试访问销售项目他们无权访问的页面,它应该 return 一个错误页面。我试着用谷歌搜索答案,但我不确定我找到的答案是否是解决我的问题的最佳方法。我看到了使用 Django Groups 的解决方案,但我不确定它是如何工作的(所以如果有人能澄清它会很棒!)。我希望有一个解决方案,在视图或序列化器中有一个检查层,并从那里推断出 request.user 来自哪个销售部门,因此数据是否应该发布给他们。

下面是我的 models.py 以更清楚地说明我正在使用的结构。

class UserProfile(models.Model):

    user = models.OneToOneField(User, on_delete=models.CASCADE)
    department = models.ManyToManyField('SalesDepartment', related_name='users', blank=True)
    contact_number = PhoneNumberField(blank=True)
    email = models.EmailField(max_length=255)
    email_password = models.CharField(max_length=255)
    profile_picture = models.ImageField(upload_to='profile/', default='profile/blank.png')

    def __str__(self):
         return str(self.user.username)


class SalesDepartment(models.Model):
    department_id = models.AutoField(primary_key=True)
    department_name = models.CharField(max_length=100)

    def __str__(self):
         return self.department_name

class SalesProject(models.Model):

    sales_project_id = models.AutoField(primary_key=True)
    sales_project_name = models.CharField(max_length=100)
    creation_date = models.DateField(default=timezone.localdate)
    sales_department = models.ForeignKey('SalesDepartment', on_delete=models.CASCADE)

    def __str__(self):
        return self.sales_project_name

UserProfile 模型与 SalesDepartment 模型有一个 M2M 字段,而 SalesProject 模型与 SalesDepartment 模型有一个外键关系。因此,我希望从 UserProfile 模型中检查用户的销售部门,并检查它是否与链接到 API 调用的特定 SalesProject 的销售部门相同,如果是, return 响应数据如常,但如果不是,则 return 响应数据错误。

感谢所有帮助,我是 Django 和 DRF 的新手,特别是,如果我在处理此授权问题时被误导,希望你们能指导我走上正确的道路。提前致谢!

from rest_framework import permissions

class IsTheUserYouWant(permissions.BasePermission):
    """
    Here I'm checking if the request.user, if the request is coming from a group that is
    allowed to perform this action or if the user here is an staff member, aka admin user.
    You can check whatever you want here since you have access to the user. So you  can
    check the sales_department like you mentioned in the question.
    """
    def has_permission(self, request, view):
        if request.user and request.user.groups.filter(name="Group You Created") or request.user.is_staff:
            return True
        return False

Views.py 用法示例

class SalesProjectSet(viewsets.ModelViewSet):
    queryset = SalesProject.objects.all()
    serializer_class = SalesProjectSerializer
    permission_classes = [IsTheUserYouWant]

在 Django Admin 页面中,您可以创建一个组并将用户添加到其中。如果需要,则可以检查用户是否来自允许的组。