django - AllowAny DRF 中的 DELETE 请求所需的权限?
问题描述
我在这里寻找一些澄清。
我已经构建了一个连接到 Django Rest Framework (DRF) 的反应应用程序。该应用程序是完全私有的,这意味着未经身份验证的任何人都无法做任何事情。为此,我使用了 TokenAuthentication(现在,因为我认为 SessionAuthentication 会更安全)。
我很难理解这一点:
- 我可以使用我的令牌进行身份验证并设置适当的标头(授权)。
- 我可以毫无问题地执行 GET/POST/PATCH 请求
- 但是:删除请求不起作用:我收到 401 - 未经授权的错误。但是我的标头和我的令牌就在那里。我正在使用 DELETE 请求从我的数据库中删除对象。
我找到了一种让它工作的方法:通过用@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.
解决方案
找到了!指向删除方法的 url 中没有尾部斜杠。
但是,DRF 没有给出 404 错误或其他什么,而是以 401(未经授权)错误响应。这让我在授权中寻找错误。
但仍然对此感到困惑:通过设置 @permission_classes((AllowAny, )) 装饰器,我的前端似乎不需要在预检后继续使用尾部斜杠。如果没有装饰器(因此具有正确的权限),React 不想在预检后继续。如果您在 url 中添加斜杠,一切正常。那么这里发生了什么?allowAny 是否绕过 CORS?CORS 是否需要尾部斜杠?
如果有人能够向我解释这种行为,我将不胜感激。
谢谢大家看!!
推荐阅读
- c# - 在选定的索引更改不应包括 datagridview asp.net 中的第一列
- c# - 如何汇总结果表中的所有数量值并将总和与总值进行比较?
- visual-studio - 通过 Vnet 在本地创建 SSIS 包
- python - 检查字符串的所有字母之间是否有空格
- multithreading - 限制同时运行的线程数
- python - 比较 JSON 路径是否与索引等价
- logging - 声纳问题:确保此记录器的配置是安全的
- javascript - 如何找到嵌套在 JSON 中的列的最大值?
- c# - 列表中的所有项目都获得相同的值
- java - 从 Spring 项目中读取 Gitlab 的属性文件