2017-04-13 100 views
0

我們有一個使用REST框架的Django應用程序。它是一個nginx,redis,芹菜,gunicorn和PostgreSQL設置。只有一個App服務器。Django,Django REST框架,Internet Explorer和CSRF令牌丟失或不正確

我們的AJAX調用使用此功能:

$.ajaxSetup({ 
    beforeSend: function (jqXHR, settings) { 
     ... 
     jqXHR.setRequestHeader("X-CSRFToken", secureCheck.reqCSRFToken()); 
}) 

if ($currentForm.attr('method') != 'POST') { 
    if ($currentForm.attr('method') != '') { 
     var typeRequest = $currentForm.attr('method'); 
     headersRequest= {'X-HTTP-Method-Override': typeRequest}; 
    } 
} 

var jqxhr = $.ajax({ 
     headers: headersRequest, 
     url: url, 
     type: 'POST', 
     dataType: dataType, 
     data: params, 
     async: async 
    }); 
    jqxhr 
     .done(function (data, textStatus, jqxhr) { 

呼叫發送到這一點:

@api_view(['POST']) 
def save(request): 
    ..... 
    return HttpResponse(json.dumps(save_results_and_errors, cls=DjangoJSONEncoder), 'application/json') 

settings.py:

REST_FRAMEWORK = { 
# Use Django's standard `django.contrib.auth` permissions, 
# or allow read-only access for unauthenticated users. 
'DEFAULT_PERMISSION_CLASSES': [ 
    'rest_framework.permissions.IsAuthenticated', 
], 
'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.SessionAuthentication', 
), 

也:

'django.middleware.csrf.CsrfViewMiddleware' 

我們從來沒有得到任何與CSRF相關的錯誤,除了一些人,六分之一的人使用Internet Explorer(版本9或11)。 「save」函數不斷返回錯誤{「detail」:「CSRF失敗:CSRF令牌丟失或不正確。」}。

清除IE歷史記錄,緩存和Cookie沒有奏效。解決此問題的唯一方法是重新啓動計算機(??? !!)。

我該如何追蹤此行爲?我們在任何網頁中都沒有任何iframe。我們的日誌文件中沒有任何內容與此問題有關。

有沒有人有這方面的線索?

回答

1

找到了!那麼,它是由微軟文檔...

我們的生產程序有兩個登錄方案:

  1. 外網(域名/外網/)。
  2. intranet(subdomain.domain/intranet /):將在幾個月內被替換爲子域名/ intranet。

如果我們登錄到外部網,然後登錄到內部網,我們有兩個與該域相關的csrf令牌。因此,reqCSRFToken()獲取兩個CSRF令牌並且使用了錯誤的(第一個匹配「csrftoken」),因爲Internet Explorer將域cookie發送到子域。

reqCSRFToken: function() { 
    var csrfTokenValeur = secureCheck.reqCookie('csrftoken'); 
    return csrfTokenValeur; 
}, 

reqCookie: function (name) { 
    var cookieValue = null; 
    if (document.cookie && document.cookie != '') { 
     var cookies = document.cookie.split(';'); 
     for (var i = 0; i < cookies.length; i++) { 
      var cookie = jQuery.trim(cookies[i]); 
      // Does this cookie string begin with the name we want? 
      if (cookie.substring(0, name.length + 1) == (name + '=')) { 
       cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 
       break; 
      } 
     } 
    } 
    return cookieValue; 
}, 

https://stackoverflow.com/a/17371607/2257881 https://blogs.msdn.microsoft.com/ieinternals/2009/08/20/internet-explorer-cookie-internals-faq/

相關問題