繁体   English   中英

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

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

我遇到了 Django Rest Framework 和 CSRF 配置的问题。 我知道在这个主题上有很多类似的帖子(比如这个Django Rest Framework remove csrf ),但大多数都不适用(我没有使用 SessionAuthentication,也没有使用 Django 模板),而且 DRF 处理 CSRF 的方式仍然不清楚对我来说。

这是情况:

  • 我有一个 DRF 应用程序充当后端 API,具有多个路由,带有令牌身份验证 (JWT)
  • 我还有一个单独的前端与我的 API 通信。 两者都在同一个域中(比如https://example.comhttps://example.com/backend
  • 我在 DRF 端有一个简单的APIView用于注册,我需要在其上发送 POST 请求。 此视图不需要身份验证。

当我发送 POST 请求时,我收到403 Forbidden error并显示以下消息: detail "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。

我在这里做错了什么?

PS:我还有另一个公共视图(登录页面),它工作正常。

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

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

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 令牌。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM