Jquery CORS、Ajax和CSRF

Jquery CORS、Ajax和CSRF,jquery,ajax,cookies,cors,django-csrf,Jquery,Ajax,Cookies,Cors,Django Csrf,django应用程序中的CSRF预防支持通过cookie将CSRF令牌发送到客户端,并在头(X-CSRFToken)或cookie中接受来自客户端的CSRF令牌。这适用于非CORS、非AJAX web应用程序。但是,如果您a)有一个通过AJAX与服务器通信的单页web应用程序,以及b)单页web应用程序托管在与服务器(CORS)不同的域中,则它似乎不起作用 问题在于,由于CORS限制,单页webapp(来自域1)无法使用xhr.getResponseHeader或getCookie读取服务器域(

django应用程序中的CSRF预防支持通过cookie将CSRF令牌发送到客户端,并在头(X-CSRFToken)或cookie中接受来自客户端的CSRF令牌。这适用于非CORS、非AJAX web应用程序。但是,如果您a)有一个通过AJAX与服务器通信的单页web应用程序,以及b)单页web应用程序托管在与服务器(CORS)不同的域中,则它似乎不起作用

问题在于,由于CORS限制,单页webapp(来自域1)无法使用xhr.getResponseHeader或getCookie读取服务器域(域2)Cookie。如果javascript webapp无法读取cookies,它如何向服务器发送适当的CSRF令牌

xhr.getResponseHeader api在检索Set-Cookie或Set-Cookie2头(按规范)时受到限制,支持CORS的各种浏览器似乎都实施了这一限制。类似地,getCookie JS函数将读取webapp域(domain1)中的所有非httpOnly cookie,但不会读取服务器在其域(domain2)中设置的cookie


这在非CORS情况下不是问题,但在我们的应用程序中,我们希望将API托管在与客户端webapp不同的域中。有什么建议吗

我想我也遇到了同样的问题,通过服务器端和客户端的结合解决了这个问题。服务器端(Django Python):

启动时的客户端:

$.ajaxPrefilter(function(options, originalOptions, jqXHR)
{
    options.crossDomain =
    {
        crossDomain: true
    };
    options.xhrFields =
    {
        withCredentials: true
    };
});

function csrfSafeMethod(method)
{
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup(
{
    crossDomain: false, // obviates need for sameOrigin test
    beforeSend: function(xhr, settings)
    {
        if (!csrfSafeMethod(settings.type))
        {
            xhr.setRequestHeader("X-CSRFToken", csrf);
        }
    }
});
为了更好地衡量,$.ajax调用自己:

$.ajax(
{
    type: "POST",
    url: theUrl,
    data: theData,
    contentType: 'application/x-www-form-urlencoded',
    dataType: 'json',
    xhrFields:
    {
       withCredentials: true
    }
});
对我来说,我所缺少的和头撞到墙上的是这一部分:

xhrFields:
{
   withCredentials: true
}

希望这对某人有所帮助。

您解决过这个问题吗?听起来你和我有同样的问题。不,从来没有解决过。如果这个问题还没有解决,你可以试试:有趣。我相信我们正在做上面描述的所有事情,除了在ajax请求中设置crossDomain:false。我认为我们已经明确地设置了crossDomain:true。我会调查的。谢谢
xhrFields:
{
   withCredentials: true
}