在 django rest 框架上获取 CSRF 令牌丢失错误(使用 TokenAuthentication)public APIView

Getting CSRF token missing error on a django rest framework (with TokenAuthentication) public APIView

我在使用 Django Rest Framework 和 CSRF 配置时遇到问题。 我知道有很多关于这个主题的类似帖子(比如这篇 ),但其中大部分都不适用(我没有使用 SessionAuthentication,也没有使用 Django 模板),并且 DRF 处理 CSRF 的方式仍然不清楚对我来说。

情况如下:

当我发送 POST 请求时,我收到带有以下消息的 403 Forbidden errordetail "CSRF Failed: CSRF token missing or incorrect."

这是我的观点:

class RecaptchaVerifyView(APIView):
    permission_classes = []
    serializer_class = ReCaptchaSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            return Response({'success': True}, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

我读到 DRF 禁用 CSRF,但我不使用的 SessionAuthentication 除外。我还读到空 permission_classes 应该可以解决大部分问题。所以我想我不需要添加 csrf_exempt 装饰器(顺便说一句,我尝试过但没有成功)。

urls.py中的路由声明如下:

urlpatterns = [
    ...
    path('recaptcha_verify/', RecaptchaVerifyView.as_view(), name='recaptcha_verify'),
    ...
]

最后,一些相关的django设置:

MIDDLEWARE = [
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

...

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
}

此外,我不确定如何处理与 CSRF 相关的设置,例如 SESSION_COOKIE_HTTPONLYSESSION_COOKIE_SECURECSRF_COOKIE_SECURESESSION_COOKIE_NAMECSRF_COOKIE_NAME ,即使是 CSRF 中间件本身。不管我是否需要它们。

根据我目前所读的内容,我认为我根本不应该为 CSRF 而烦恼,因为 DRF 强制执行默认的 Django 行为,并且我使用的是 TokenAuthentication 而不是 SessionAuthentication。

我做错了什么?

P.S:我还有另一个 public 视图(登录页面),效果很好。

除了空的 permission_classes 列表之外,设置中缺少的关键行是 authentication_classes = ()

所以我的 APIView class 现在看起来像这样:

class RecaptchaVerifyView(APIView):
    permission_classes = ()
    authentication_classes = ()

    @swagger_auto_schema(responses={status.HTTP_200_OK: openapi.Response("")})
    def post(self, request, *args, **kwargs):
        serializer = ReCaptchaSerializer(data=request.data)
        if serializer.is_valid():
            return Response({'success': True}, status=status.HTTP_200_OK)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

注册视图也是如此。花了几个小时在这个上,但是现在 DRF 文档说明没有明确声明 authentication_classes,默认 SessionAuthentication 是强制执行的,因此这需要 CSRF 令牌。