首页 > 解决方案 > AllowAny DRF 中的 DELETE 请求所需的权限?

问题描述

我在这里寻找一些澄清。

我已经构建了一个连接到 Django Rest Framework (DRF) 的反应应用程序。该应用程序是完全私有的,这意味着未经身份验证的任何人都无法做任何事情。为此,我使用了 TokenAuthentication(现在,因为我认为 SessionAuthentication 会更安全)。

我很难理解这一点:

我找到了一种让它工作的方法:通过用@permission_classes((AllowAny, ))它装饰我的视图类就可以了。但我对此并不满意。

那么,这是为什么呢?

在我的设置文件中,我有:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated', )
}

在 DRF 文档(链接)中,它说:

DELETE 请求要求用户对模型具有删除权限。

但是,我的用户是管理员,为什么我需要显式添加这个装饰器?

我究竟做错了什么?这不是最好的方法。如果我使用外部 API 客户端(如 Postman - 我使用 Paw)发出请求,为什么没有装饰器它会运行良好?

作为参考,是我的简化视图类:

@permission_classes((AllowAny, ))
class ObservationAPIView(APIView):

    def delete(self, request, test_id, observation_id, format=None):

        # see if my object exists
        try:
            obs_object_to_delete = Observation.objects.get(pk=observation_id)
            test_obj = Test.objects.get(pk=test_id)

        except ObjectDoesNotExist:
            errormsg = {
                'observation id': observation_id,
                'test id': test_id,
                'message': 'Cannot delete this object. Observation ID or test ID not found.'
            }
            return Response(errormsg, status=status.HTTP_404_NOT_FOUND)

        # it exists, delete it 
        obs_object_to_delete.delete()

        # return the test data (not the deleted object)
        serializer = TestSerializer(test_obj, many=False)
        return Response(serializer.data)

    def patch(self, request, test_id, observation_id, format=None):

        # there is also a PATCH function to allow for edits. 
        # This does work well without the decorator.

标签: djangoreactjsauthenticationdjango-rest-frameworktoken

解决方案


找到了!指向删除方法的 url 中没有尾部斜杠。

但是,DRF 没有给出 404 错误或其他什么,而是以 401(未经授权)错误响应。这让我在授权中寻找错误。

但仍然对此感到困惑:通过设置 @permission_classes((AllowAny, )) 装饰器,我的前端似乎不需要在预检后继续使用尾部斜杠。如果没有装饰器(因此具有正确的权限),React 不想在预检后继续。如果您在 url 中添加斜杠,一切正常。那么这里发生了什么?allowAny 是否绕过 CORS?CORS 是否需要尾部斜杠?

如果有人能够向我解释这种行为,我将不胜感激。

谢谢大家看!!


推荐阅读