我们假设我有这样的URL users/{id}/objects
并且我被认证为ID等于1的用户。目前我可以访问ID等于2,3等的用户的对象。有没有人知道如何我可以阻止这个吗?
class UserObject(GenericAPIView):
permission_classes = [UserPermission]
def get(self, request, user_id):
try:
object = Object.objects.filter(user=user_id)
except Object.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = ObjectSerializer(object, many=True)
return Response(serializer.data)
class UserPermission(permissions.BasePermission):
def has_permission(self, request, view):
if request.user and request.user.is_authenticated():
return True
return False
我试过这样的方式:
serializer_class = ObjectSerializer
permission_classes = [IsAuthenticated, ]
def get_queryset(self):
return Object.objects.filter(owner=self.request.user)
def get(self, request, user_id):
try:
object = Object.objects.filter(user=user_id)
except Object.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = ObjectSerializer(object, many=True)
return Response(serializer.data)
答案 0 :(得分:2)
如果重载视图的get_queryset
只返回属于当前用户的对象,那么Django将自己处理相应的错误和响应。例如,
class MyView(GenericAPIView):
serializer_class = serializers.MySerializer
permission_classes = (IsAuthenticated,)
def get_queryset(self):
return MyModel.objects.filter(owner=self.request.user)
另见http://www.django-rest-framework.org/api-guide/generic-views/#attributes
答案 1 :(得分:1)
您只能使用IsAuthenticated
权限来检查是否有人登录,如果用户要求提供自己的数据,则可以“手动”检查。像这样:
class UserObject(GenericAPIView):
permission_classes = (IsAuthenticated,)
def get(self, request, user_id):
if (str(reques.user.id) != user_id):
return Response(status=status.HTTP_403_FORBIDDEN)
try:
object = Object.objects.filter(user=user_id)
except Object.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = ObjectSerializer(object, many=True)
return Response(serializer.data)
如果你真的想使用自定义权限,你可以不受影响地使用,并且允许你这样的许可:
class UserPermission(permissions.BasePermission):
def has_permission(self, request, view):
if (not request.user.is_authenticated()):
return False
user_id = request.path.split('/')[1]
if (str(request.user.id) == user_id):
return True
return False
注意:我建议使用第一个选项。
注意:此代码是一个示例,如果它不能立即工作,请尝试
理解这个想法并进行调整。我没有测试它,它可能需要一些调整,特别是获得user_id
frorm response.path
的部分。