【发布时间】:2021-04-06 19:44:11
【问题描述】:
我正在使用带有身份验证的 DRF。我已经实现了会话和令牌认证。第一个由我用来调试的可浏览 API 使用,第二个是实际客户端将使用的身份验证。我有以下详细视图:
@api_view(['GET', 'PUT', 'DELETE'])
@permission_classes([permissions.IsAuthenticated, IsTrainingOwner]) # this view is only available to authenticated users
def training_detail(request, pk, format=None):
"""
Retrieve, update or delete a training. Need to be authenticated
"""
print(request.user)
try:
training = Training.objects.get(pk=pk)
except Training.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = TrainingSerializer(training)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = TrainingSerializer(training, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
training.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
如您所见,我正在使用自定义权限:
class IsTrainingOwner(permissions.BasePermission):
"""
Custom permission to only allow owners of an object to see and edit it
"""
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in permissions.SAFE_METHODS:
print("Object owner: ", obj.owner)
print("Request user: ", request.user)
return True
# Instance must have an attribute named `owner`.
print("Object owner: ", obj.owner)
print("Request user: ", request.user)
return obj.owner == request.user
当我使用 DRF 可浏览 API 时,此自定义权限被正确调用,对象所有者和请求用户的打印显示在我的控制台中。
但是,当我使用 Postman 测试 Token 权限时,根本没有调用“has_object_permission”方法(我在控制台中没有看到任何打印),我可以在发送时修改用户 A 的培训标头中用户 B 的令牌。
我已经阅读了有关此问题的 DRF 文档,然后决定尝试通用视图:
class TrainingDetail(generics.RetrieveUpdateAPIView):
permission_classes = [permissions.IsAuthenticated, IsTrainingOwner]
queryset = Training.objects.all()
serializer_class = TrainingSerializer
使用通用视图效果很好,并且可以正确调用自定义权限。
所以,我的问题是: 当我使用使用会话身份验证的可浏览 API 并且我需要切换到通用视图版本才能使自定义权限与 POSTMAN 一起使用时,为什么自定义权限可以与基于函数的视图版本一起使用?
感谢您的帮助:)
【问题讨论】:
标签: django authentication django-rest-framework