2016-03-08 110 views
6

我已經在SO上看到了很多關於此的內容,但沒有什麼能解決我的問題。Django 1.9 AJAX表單CSRF令牌403錯誤 - 「CSRF cookie未設置」

問題:

隨着CSRF中間件啓用,Django的有403對AJAX的形式要求作出響應,指出:

「未設置CSRF餅乾。」

documentation,一個JS的功能被實現,則該設置的自定義「X-CSRFToken」頭。

它將按預期工作,得到「csrftoken」從瀏覽器並將其發佈的cookie隨着AJAX請求:

x-csrftoken: 1a0u7GCQG0wepZHQNThIXeYpMy2lZOf2 

但響應仍然是403

嘗試的解決方案:

我已經試過了我可以在SO或網上找到的所有東西,具體如下:

  • 檢查中間件已啓用:

    MIDDLEWARE_CLASSES = [ 
        ... 
        'django.middleware.common.CommonMiddleware', 
        'django.middleware.csrf.CsrfViewMiddleware', 
        'django.contrib.auth.middleware.AuthenticationMiddleware', 
        ... 
    ] 
    
  • 不同的瀏覽器啓用了餅乾;

  • @ensure_csrf_cookie裝飾我的視野;

  • 在我的模板中設置{% csrf_token %};

  • 使用render快捷方式,它採取正確的請求上下文;

  • 在我的settings.py中設置自定義CSRF_COOKIE_NAMECSRF_HEADER_NAME;

  • 明確設置CSRF_COOKIE_SECURE = FalseCSRF_COOKIE_HTTPONLY = False;

  • 明確設置CSRF_TRUSTED_ORIGINS設置;

  • 測試開發和生產服務器;

  • 即使request.META["CSRF_COOKIE_USED"] = True在我看來,正如有人建議。

而且一無所獲。

頭:

如果我在視圖中使用@csrf_exemptprint(request.META),很顯然,自定義標題「X-CSRFToken」出現在請求和格式化根據Django文檔,以「HTTP_」前綴,用下劃線代替連字符,全部大寫:「HTTP_X_CSRFTOKEN」

更重要的是,它與Django設置的cookie匹配。

餅乾:

奇怪的是,如果我嘗試print(request.COOKIES)在我看來,在頁面和形式加載,我可以看到「csrftoken」 cookie的存在,但字典是空的AJAX請求 。這可能是問題嗎?

不顧一切地找到實際上錯誤的東西。謝謝您閱讀此篇。

+0

你能告訴你的實際看法和JavaScript? – Alasdair

+0

你用什麼來發送AJAX請求? jQuery的? – Smile0ff

+0

@ Smile0ff:提取API。 – Nevertheless

回答

6

好的,問題很簡單:

默認情況下,提取API沒有發送憑據。據MDN

憑據只讀請求接口的屬性指示 用戶代理是否應該從其他域發送cookies在 跨域請求的情況下。這與XHR的 withCredentials標誌類似,但具有三個可用值。

默認爲omit,它從不發送cookie。你只需要添加same-originfetch()函數參數:

fetch(formUrl, { 
    ... 
    credentials: 'same-origin', 
    ... 
}) 

你會好起來:)