2016-02-26 62 views
5

我从我的本地主机执行POST请求到远程django api时收到CSRF令牌缺失或不正确的错误。CSRF令牌丢失或不正确。 Django + AngularJS

我对AngularJS设置:

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

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

}]); 

但IM仍然得到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 
+0

这是一个重复? http://stackoverflow.com/questions/18156452/django-csrf-token-angularjs –

+1

不是因为我仍然有问题。 –

+0

你的django restframework设置是什么? –

回答

1

由于@克里斯·霍克斯指出,这个计算器回答@Ye刘给出

由于角度应用不被Django的服务,为了让需要设置的Cookie为 ,角度应用需要首先对django 进行GET请求。

我验证了只要你不使http获取请求,csrftoken cookie不会被设置。所以只有

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

将无法​​正常工作。你首先需要做的,如果不是真正的,然后模拟HTTP请求django rest_framework

更新:您的意见促使我进一步研究它,请仔细阅读本blog其中已经提到,

CLIENT端生成CSRF的令牌。让客户端生成并发送 相同的唯一秘密值,包括Cookie和自定义HTTP标头中的 。考虑到一个网站只允许读/写自己的域的Cookie ,只有真正的网站可以在两个 头

因此,让这种单一的请求第一次尝试发送相同的值。

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

你在哪里注射$cookies控制器/服务。

如果有效,那么可能会写入interceptors将是不错的选择,并且可以帮助您进行调试。

我相信你使用的AngularJs版本至少有1个。2,请参阅本changeset 并在最近提交角http服务检查CSRF与此代码,

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

所以这是必要的,你要发送同样的道理,它存在于饼干。

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

+0

我在页面加载时做了一个get请求。所以我得到CSRFTOKEN的回应。正如你可以在上面发布的resquest头文件中看到的那样,cookie csrftoken = hiYq1bCNux1mTeQuI4eNgi97qir8pivi;被设置。当时正在发生的是当我尝试做另一个请求时,django说我没有发送令牌。我注意到头HTTP_X_CSRFTOKEN没有发送。 –

+0

Thx为你提供帮助。但我想它只会在本地机器上运行,不会真正起作用。我会稍后将其上传到服务器并进行测试。 –

0

如果您使用的$ HTTP在AngularJS为Ajax请求,如果你正面临任何CSRF令牌问题,那么使用这个:

$http.defaults.xsrfCookieName = 'csrftoken'; 
$http.defaults.xsrfHeaderName = 'X-CSRFToken'; 
相关问题