如果我以user1
的身份登录并且正在访问名为ViewSet
的{{1}},则RecipeSubmissionViewSet
会提取用户想要的食谱的POST
提交。假设recipe_id
模型上有一个user1
字段,并且我可以将其与request.user进行比较,如何确保user2
不提交Recipe
的食谱?我应该为此使用权限类还是有更好的方法?我是从后端的角度讲的,没有考虑到前端当然会过滤掉属于用户的食谱,而只会向他们展示自己的食谱。
答案 0 :(得分:2)
可以有两种方法。您可以过滤掉查询集或定义权限类。
如果您这样重写get_queryset
方法。
class RecipeSubmissionViewSet(...):
def get_queryset(self):
return Recipe.objects.filter(owner=self.request.user)
# you can also use filtration based on action name like this
# if self.action == 'update':
# return Recipe.objects.filter(owner=self.request.user)
# return Recipe.objects.all()
用户将获得 404 响应,并且将永远无法访问自己拥有的对象。
第二选择是权限等级。您可以定义自定义权限类,并像这样显式检查所有权。
from rest_framework.permissions import BasePermission
class RecipeSubmissionPermission(BasePermission):
def has_object_permission(self, request, view, obj):
# you can also check permission here based on action
# if view.action == 'update':
# pass
return request.user.is_authenticated and obj.owner == request.user
class RecipeSubmissionViewSet(...):
permission_classes=[RecipeSubmissionPermission]
在这种情况下,用户将获得 403 权限错误。
如果同时使用这两种方法。首选 404 。
您可以使用任意一种方法,也可以同时使用这两种方法。权限类看起来更像是编程的和结构化的方式,但是用户将知道具有此ID的对象存在,但他没有权限对其进行更新。但是,如果您覆盖查询集,则用户甚至无法知道对象是否存在,因此更加安全。
答案 1 :(得分:0)
您是否正在使用django身份验证系统?然后,您应该能够在视图中访问request.user
并相应地设置owner
字段。
编辑:我想我误解了这个问题。
但是this可以提供帮助,Nafees Anwar看起来不错。
答案 2 :(得分:0)
Nafees的答案几乎可以解决。
我一直在开发对用户具有多租户的微服务,针对它们的规则(根据我的项目规范)是:
我这样做的方法很简单。
禁止查看/编辑他人的东西
def get_queryset(self):
return self.queryset.filter(user=request.user)
并且为了禁止编辑其他人的东西,这是在序列化器上完成的
class SomeSerializer(...):
def validate(self, data):
data.pop('user', None)
data['user'] = self.context['request'].user
使用上述方法,如果user1请求user2信息,则视图集中的get_queryset
将始终返回404。
validate
函数将阻止分配。就是如果user1创建了一个分配给user2的东西,而是分配了user1,这就是我在应用程序中需要的行为,那么如果需要,您可以始终raise serializers.ValidationError("You cannot assign stuff to user2")
代替,而不是像我在用例中那样重新分配用户。通过在validate
中使用此逻辑,您可以确保任何可写函数对于该序列化器始终具有相同的行为。
希望这会有所帮助。