5

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

My settings on 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.

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

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

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
4
  • is this a duplicate? stackoverflow.com/questions/18156452/… Commented Feb 26, 2016 at 20:58
  • 1
    not since i still have the problem. Commented Feb 26, 2016 at 21:01
  • what are your django restframework settings? Commented Feb 27, 2016 at 8:16
  • we're not using the Django Rest Framework, our API is built natively within Django Commented Mar 1, 2016 at 16:21

2 Answers 2

1

As @Chris Hawkes pointed to this stackoverflow answer given by @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.

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

$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.

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

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.

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,

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.

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

Sign up to request clarification or add additional context in comments.

2 Comments

Im doing a get request on page load. so i get the CSRFTOKEN with the response. as you can see on the resquest header that i posted above, the cookie csrftoken=hiYq1bCNux1mTeQuI4eNgi97qir8pivi; is setted. whast is happening is when i try to do another request django is saying that im not sending the token. I notice that the header HTTP_X_CSRFTOKEN is not sent.
Thx for you help. But i guess it wont really work as long as im on local machine. i will upload it later to the server and test it out.
0

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

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.