CSRF令牌丢失或不正确。 Django + AngularJS

时间:2016-02-26 20:32:54

标签: angularjs django api csrf django-csrf

从localhost机器向远程django api发出POST请求时,我收到CSRF令牌丢失或错误。

我在AngularJS上的设置:

.config(['$httpProvider', function($httpProvider){

$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';

}]);

但我仍然没有 CSRF令牌丢失或错误错误。

我检查发送的标头是什么,显然有角度没有发送HTTP_X_CSRFTOKEN

但我可以看到cookie csrftoken =发送的内容。

有谁知道发生了什么事?

请求标题

POST /s/login/ HTTP/1.1
Host: server.somewhere.io:8000
Connection: keep-alive
Content-Length: 290
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/plain, */*
Origin: http://localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
Content-Type: application/json;charset=UTF-8
Referer: http://localhost/thesocialmarkt/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en;q=0.8,en-US;q=0.6,pt-BR;q=0.4,pt;q=0.2
Cookie: csrftoken=hiYq1bCNux1mTeQuI4eNgi97qir8pivi; sessionid=1nn1phjab5yd71yfu5k8ghdch2ho6exc

2 个答案:

答案 0 :(得分:1)

@Chris Hawkes指出@Ye Liu给出的这个堆栈溢出答案

  

由于django不提供角度app,为了让   要设置的cookie,角度应用程序需要对django执行GET请求   第一

我确认只要您不进行http get请求,csrftoken cookie就不会被设置。所以只有

$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';

无效。你首先需要制作,如果不是真的那么模拟http获取请求到django rest_framework

更新:您的评论促使我进一步研究它,请阅读blog所提到的地方,

  

客户端生成的CSRF-TOKENS。让客户生成和发送   Cookie和自定义HTTP中的相同唯一秘密值   头。考虑到网站只允许读/写Cookie   对于自己的域,只有真实站点可以在两者中发送相同的值   头

所以我们先试试这个单一的请求。

$http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;

您将$cookies注入控制器/服务。

如果它有效,那么写interceptors可能是个不错的选择,也可以帮你调试。

我确定您使用的AngularJs版本至少为1.2,请参阅此changeset 并在最近使用此代码提交Angular http服务检查csrf,

var xsrfValue = urlIsSameOrigin(config.url)
            ? $$cookieReader()[config.xsrfCookieName || defaults.xsrfCookieName]
            : undefined;
        if (xsrfValue) {
          reqHeaders[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;
        }

因此,您必须发送cookie中存在的相同令牌。

进一步分析浏览器的使用开发者工具,以查看带有http请求的请求/响应,并分析标头和cookie。

答案 1 :(得分:0)

如果您在AngularJS中使用$ http获取ajax请求,并且如果您遇到任何CSRF令牌问题,请使用此命令:

$http.defaults.xsrfCookieName = 'csrftoken';
$http.defaults.xsrfHeaderName = 'X-CSRFToken';