簡體   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