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

时间:2021-03-27 04:54:14

I'm getting CSRF token missing or incorrect error while doing a POST request to a remote django api from my localhost machine.

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

My settings on AngularJS:

我在AngularJS上的设置:

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

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

}]);

but im still getting the CSRF token missing or incorrect error.

但我仍然得到CSRF令牌丢失或不正确的错误。

I check what headers are being sent and apparently angular is not sending HTTP_X_CSRFTOKEN.

我检查发送的标题是什么,显然angular不发送HTTP_X_CSRFTOKEN。

But I can see that the cookie csrftoken=something is sent.

但我可以看到cookie csrftoken =发送的东西。

Does anyone know what is going on?

有谁知道发生了什么?

Request Header

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 个解决方案

#1


1  

As @Chris Hawkes pointed to this * answer given by @Ye Liu

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

Since the angular app isn't served by django, in order to let the cookie to be set, angular app needs to do a GET request to django first.

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

I verified that as long as you don't make http get request, csrftoken cookie doesn't get set. So only

我验证了,只要你不进行http get请求,csrftoken cookie就不会被设置。所以只有

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

would not work. You first need to make if not real then mock http get request to django rest_framework.

不行。你首先需要制作,如果不是真的然后模拟http获取请求到django rest_framework。

Update: Your comments pushed me to further study it, Please read this blog where is has mentioned as,

更新:您的评论促使我进一步研究它,请阅读此博客,其中提到了,

CLIENT-SIDE GENERATED CSRF-TOKENS. Have the clients generate and send the same unique secret value in both a Cookie and a custom HTTP header. Considering a website is only allowed to read/write a Cookie for its own domain, only the real site can send the same value in both headers

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

So lets try with this single request first.

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

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

where you are injecting $cookies to the controller/service.

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

If it works then may be writing interceptors would be good choice, and would help you to debug as well.

如果它工作,那么可能是编写拦截器将是一个很好的选择,并将帮助您调试。

I am sure you are using AngularJs version at least 1.2, See this changeset and in recent commit Angular http service checking csrf with this code,

我确定你使用AngularJs版本至少1.2,请参阅此变更集,并在最近使用此代码提交Angular http服务检查csrf,

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

So it's necessary that you are sending same token which is present in cookie.

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

Further to analyse use developer tool of your browser to see request/response with the http request and analyse headers and cookies.

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

#2


0  

if you are using $http in AngularJS for ajax request and if you are facing any CSRF token issue then use this:

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

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

#1


1  

As @Chris Hawkes pointed to this * answer given by @Ye Liu

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

Since the angular app isn't served by django, in order to let the cookie to be set, angular app needs to do a GET request to django first.

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

I verified that as long as you don't make http get request, csrftoken cookie doesn't get set. So only

我验证了,只要你不进行http get请求,csrftoken cookie就不会被设置。所以只有

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

would not work. You first need to make if not real then mock http get request to django rest_framework.

不行。你首先需要制作,如果不是真的然后模拟http获取请求到django rest_framework。

Update: Your comments pushed me to further study it, Please read this blog where is has mentioned as,

更新:您的评论促使我进一步研究它,请阅读此博客,其中提到了,

CLIENT-SIDE GENERATED CSRF-TOKENS. Have the clients generate and send the same unique secret value in both a Cookie and a custom HTTP header. Considering a website is only allowed to read/write a Cookie for its own domain, only the real site can send the same value in both headers

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

So lets try with this single request first.

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

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

where you are injecting $cookies to the controller/service.

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

If it works then may be writing interceptors would be good choice, and would help you to debug as well.

如果它工作,那么可能是编写拦截器将是一个很好的选择,并将帮助您调试。

I am sure you are using AngularJs version at least 1.2, See this changeset and in recent commit Angular http service checking csrf with this code,

我确定你使用AngularJs版本至少1.2,请参阅此变更集,并在最近使用此代码提交Angular http服务检查csrf,

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

So it's necessary that you are sending same token which is present in cookie.

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

Further to analyse use developer tool of your browser to see request/response with the http request and analyse headers and cookies.

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

#2


0  

if you are using $http in AngularJS for ajax request and if you are facing any CSRF token issue then use this:

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

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