如何在 Django REST 框架中为 HTTP_405_METHOD_NOT_ALLOWED 状态码正确设置 Allow header

How to correctly set Allow header for a HTTP_405_METHOD_NOT_ALLOWED status code in Django REST framework

我目前正在寻找禁用 API 端点的某些方法 - 作为增加的安全性。我正在使用 DRF 建议使用的状态代码,即针对我的情况,“HTTP_405_METHOD_NOT_ALLOWED” - 然而,在我看来,尽管这有效,但 headers 仍然说方法在允许。请参阅下面的屏幕截图:

如您所见,我正在执行 GET 请求 - 但 Allow header 表示没问题 - 即使状态代码已正确应用。

剥离示例代码:

class TokenValidateView(APIView):
    def get(self, request, format=None):
        return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED, headers=?)

我认为我需要在 headers 字典中设置一些内容(我在我不太确定需要做什么的地方添加了 ?)作为参数之一在 Response() 函数中,但我不确定这是否是 DRF 本身的错误?当然,当该状态代码被传递时,它应该相应地设置在 headers 中吗?

N.B。我也试过将 headers = { 'Allow': 'POST' } 添加到 Response() 参数,但这似乎不起作用...

当你重写视图的get方法时,GET被django-rest-framework自动添加到Allowheader,无论什么Response你return。如果你想要 return 405 Not Allowed.

,你可以简单地删除 get 方法

如果出于某种原因,您想保留 get 方法并且不将 GET 包含在 Allow header 中,您可以覆盖 allowed_methods 属性 在您看来:

@property
def allowed_methods(self):
    allowed_methods = super().allowed_methods
    allowed_methods.remove('GET')
    return allowed_methods

由于您正在使用 APIView class,它将允许在您的视图 class 中定义的所有方法。 DRF 响应允许 HTTP GET 方法,因为您已在视图中定义。


下面的视图 class 将允许 HTTP GET,HTTP POST,HTTP PATCH,HTTP PUT and HTTP DELETE

class TokenValidateView(APIView):
    def get(self, request, format=None):
        # something
        return Response("this is HTTP GET")

    def post(self, request, format=None):
        return Response("this is HTTP POST")

    def patch(self, request, format=None):
        return Response("this is HTTP PATCH")

    def put(self, request, format=None):
        return Response("this is HTTP PUT")

    def delete(self, request, format=None):
        return Response("this is HTTP DELETE")

正如我上面所说,响应 class 检查视图 class 中的 http 方法 不是他们的回应

因此,如果您想从 Allowed Methods 中删除 HTTP GET 方法,只需从视图 class

中删除 get() 方法
class TokenValidateView(APIView):
    <b># remove the "get()" method</b>
    <b><strike>def get(self, request, format=None):</strike></b>
        <b><strike># something</strike></b>
        <b><strike>return Response("this is HTTP GET")</strike></b>

    def post(self, request, format=None):
        return Response("this is HTTP POST")

    def patch(self, request, format=None):
        return Response("this is HTTP PATCH")

    def put(self, request, format=None):
        return Response("this is HTTP PUT")

    def delete(self, request, format=None):
        return Response("this is HTTP DELETE")

如果您不需要该方法,请不要在子类化 ApiView 的视图上实现它。它会自动发送方法不允许的响应。