2017-04-13 98 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/

相关问题