我努力在Django REST框架上的对象创建上实施安全性。

基本上,我可以使用'has_object_permission'在对象级别实施安全性:登录的用户必须是该对象的所有者才能对其进行操作。 实际上,正如文档中所述,我缩小了查询集中的对象检索范围,因此得到了404而不是403。我认为这不是问题(甚至更好,因为它隐藏了对象的存在)

但是我不能成功地不允许另一个用户创建相关对象。

我使用ModelSerializer和ModelViewSet。

这是一些天真的片段:

models.py:

class Daddy(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=20)
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

class Kiddy(models.Model):
    title = models.CharField(max_length=12)
    daddy = models.foreignKey(Daddy, on_delete=models.CASCADE)

serializers.py:

class KiddySerializer(serializers.ModelSerializer):
    class Meta:
        model = Kiddy
        fields = '__all__'

viewsets.py:

class KiddyViewSet(viewsets.ModelViewSet):
    serializer_class = KiddySerializer
    queryset = User.objects.none()

    permission_classes = (IsAuthenticated, IsOwner, )

    def get_queryset(self):
        dad_uuid = self.kwargs['dad']
        return Kiddy.objects.filter(daddy__pk=dad_uuid).filter(daddy__owner=self.request.user)

router.py:

router = routers.DefaultRouter()
router.register(r'dad', KiddyViewSet, base_name='kid')

urls.py:

path('api/<uuid:cv>/', include(router.urls))

使用这些网址访问对象: http://..../api/4ecddcdd-1c0a-4d0b-8254-b0c0d2607e6d/-- >列出所有孩子

http://..../api/4ecddcdd-1c0a-4d0b-8254-b0c0d2607e6d/1 --->对象小子

实际上,由于使用uuid,我得到了一些安全保障,这很难猜到...

Permissions.py:

class IsOwner(permissions.BasePermission):
"""
Object-level permission to only allow owners of an object to edit it.
Assumes the model instance has an `owner` attribute.
"""

def has_object_permission(self, request, view, obj):
    if request.user != obj.daddy.owner:
        return False
    else:
        return True

如果使用错误的所有者登录,则可以创建相关的Kiddy对象!

我想,我必须以“ has_permission”类型实现此权限。 但是我不知道如何访问那里的对象,因为参数是请求和查看...

在这里,他找到了解决方案。 但这根本不是通用的,因为我将需要对每个相关对象的自定义权限...我得到了很多! 在Django REST Framework中检查相关对象的权限

任何想法?

#1楼 票数:0

好的,我解决了这个问题:-)

正如我怀疑的那样,在Permissions.py中,我添加了以下“ has_permission”:

class IsOwnerParent(permissions.BasePermission):
    def has_permission(self, request, view):
        daddy = Daddy.objects.get(pk=view.kwargs['dad'])
        return daddy.owner == request.user

并将其添加到我的ModelViewSet类中:

class KiddyViewSet(viewsets.ModelViewSet):
    serializer_class = KiddySerializer
    queryset = User.objects.none()

    permission_classes = (IsAuthenticated, IsOwner, IsOwnerParent)

    def get_queryset(self):
        dad_uuid = self.kwargs['dad']
        return Kiddy.objects.filter(daddy__pk=dad_uuid).filter(daddy__owner=self.request.user)

因此,实际上,此处提供的解决方案在Django REST Framework中检查相关对象的权限确实有效。 实际上,它非常通用,因为我的许多对象都与“爸爸”对象有关。

实际上,现在检索对象列表的行为看起来更“正常”:我收到403错误而不是404错误。

我认为这种用例非常普遍:用户只能创建与其拥有的对象相关的对象,并且也只能更新和删除其拥有的对象。

但是也许可以做一个更好的方法?

  ask by stockersky translate from so

未解决问题?本站智能推荐:

1回复

检查DjangoRESTFramework中相关对象的权限

我已经定义了以下模型 以及使用REST Framework Extensions中的NestedViewsetMixin的以下视图NestedViewsetMixin 所以,要访问FlightUpdates与相关Flight ,网址是/flights/1/updates/ 。 我想确
2回复

DRF权限最佳实践DRY

当前根据用户类型在 DRF 中查看权限的最佳方法是什么? 在我的结构中有几个user_types ,例如TEAM_LEADER不能创建team对象,但可以看到teams列表。 这意味着对于同一个类视图,我想对 POST 和 GET 使用不同的权限。 我希望尽可能地做到这一点,并且我正在尝试遵循瘦视图
3回复

Django/drf-删除方法

我想从我的“ Likes表中删除“ Likes 。 为此,我正在使用axios({ method: "delete", url: http://127.0.0.1:8000/api/delete/ , params: { companyid: xyz } })从前端进行 axios 调用它应该删除其
2回复

DRF自定义权限未触发

我为 drf 项目编写了一个自定义权限类来保护我的视图: 视图.py 我的权限类: 权限.py 不幸的是,即使应该,这个权限类也没有阻止我的观点。 我不知道为什么。 我错过了什么?
2回复

DRF:始终应用默认权限类

在视图中定义权限后,我想始终检查发出请求的用户是否具有该权限。 假设我有一个基本的权限检查,如下所示: 我已将其添加为我的settings默认权限: 这是可行的,但是一旦我在View中定义permission_classes ,默认值就会被覆盖。 是否有任何清洁正确的方法? 我可
1回复

Django-自定义对象权限视图

我正在尝试授予店主查看权限。 所以我创建了一个文件,在其中创建了不同的权限。 在我的许可下,我首先检查用户是否使用 has_permission 函数登录。 我现在正在尝试使用 has_object_permission 函数确定用户是否实际拥有该商店。 不幸的是,我觉得我的功能没有正确执行。 不管
7回复

在DRF中拒绝权限时返回自定义消息

Django REST Framework有一篇关于权限的优秀文档。 我已经能够使用预制的权限类,也可以构建我自己的权限类。 但是,在某些 API 方法中,“权限被拒绝”一般消息对用户来说信息量不大。 例如,如果用户已通过身份验证但帐户已过期,最好让用户知道他的帐户已过期,而不仅仅是权限被拒绝错误
1回复

DRF:如何基于字段权限限制嵌套序列化器中的字段?

我试图根据用户权限限制序列化程序中的fields列表。 我有一个通用例程,可以对所有序列化程序执行此操作。 它在父级序列化器上运行,但在嵌套序列化器上不运行。 我有一个客户模型和一个客户资料(称为“联系人”),如下所示。 客户端配置文件模型是用户模型的扩展(一对一关系)。 class