"CSRF Failed: CSRF token missing or incorrect" with Django #585

Open
opened 2017-01-23 08:09:30 +00:00 by keeper · 19 comments
keeper commented 2017-01-23 08:09:30 +00:00 (Migrated from github.com)

Hi. I'm using django + django-rest-framework as backend and try to use ng2-file-upload to upload file, but failed with CSRF token missing.

I think I've correctly setup XSRFStrategy so other POST/PUT/DELETE requests work, and when uploading in request header there's csrftoken in the cookie, but seems ng2-file-upload doesn't work with CSRF token very well.

Here's request header:

POST /api/upload/ HTTP/1.1
...
...
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryhMZfMzgtFvJcsxRZ
Accept: */*
Referer: http://foo.bar/uploader/
Cookie: sessionid=SID; csrftoken=CSRFTOKEN

Thank you very much

Hi. I'm using django + django-rest-framework as backend and try to use ng2-file-upload to upload file, but failed with CSRF token missing. I think I've correctly setup XSRFStrategy so other POST/PUT/DELETE requests work, and when uploading in request header there's `csrftoken` in the cookie, but seems ng2-file-upload doesn't work with CSRF token very well. Here's request header: ``` POST /api/upload/ HTTP/1.1 ... ... Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryhMZfMzgtFvJcsxRZ Accept: */* Referer: http://foo.bar/uploader/ Cookie: sessionid=SID; csrftoken=CSRFTOKEN ``` Thank you very much
grapemix commented 2017-01-28 02:43:48 +00:00 (Migrated from github.com)

there has a authToken parameter in the file uploader for your need. I already tested it works with django

there has a authToken parameter in the file uploader for your need. I already tested it works with django
keeper commented 2017-01-28 19:07:12 +00:00 (Migrated from github.com)

@grapemix:
Hi, thanks for the help. Sorry I'm pretty new to the front-end, I don't know what value I should pass to authToken parameter. Should I include the CSRF token in the string like this: DRF-TokenAuthentication, or just simply "Token" is sufficient?

I've tried both but still got the same message.

@grapemix: Hi, thanks for the help. Sorry I'm pretty new to the front-end, I don't know what value I should pass to authToken parameter. Should I include the CSRF token in the string like this: [DRF-TokenAuthentication](http://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication), or just simply "Token" is sufficient? I've tried both but still got the same message.
grapemix commented 2017-01-31 07:42:57 +00:00 (Migrated from github.com)

this.uploader.setOptions({headers: [{Authorization: 'Bearer ' + idToken}]});

this.uploader.setOptions({headers: [{Authorization: 'Bearer ' + idToken}]});
keeper commented 2017-02-09 08:32:55 +00:00 (Migrated from github.com)

I add the code to set the token, and the header also has the line
Authorization:Bearer <CSRFTOKEN> which matches the token in the cookie, but still got 403 with CSRF Failed. Guess I mess something else up, thanks the help anyway.

I add the code to set the token, and the header also has the line ```Authorization:Bearer <CSRFTOKEN>``` which matches the token in the cookie, but still got 403 with CSRF Failed. Guess I mess something else up, thanks the help anyway.
jacobdenobel commented 2017-02-09 19:23:50 +00:00 (Migrated from github.com)

I have the same issue, for some reason I can't send the CSRF token with this file uploader.

I have the same issue, for some reason I can't send the CSRF token with this file uploader.
keeper commented 2017-02-10 05:41:33 +00:00 (Migrated from github.com)

@TheAn4rch1st
I have some interesting finding in dango/csrf.py:275 (Django 1.10.5). I insert pdb.set_trace() here and CSRF token is actually passed to the backend as request_csrf_token, but the token doesn't match for some reason.

Can you also check the value to see if the token is really missing, or it's sent but doesn't match? Thanks.

Update:
Comparing to a successful uploading, I found ng2-file-upload missing salted csrf token in Request-Payload:

------WebKitFormBoundary
Content-Disposition: form-data; name="csrfmiddlewaretoken"

<SALTED_CSRFTOKEN>
@TheAn4rch1st I have some interesting finding in dango/csrf.py:275 (Django 1.10.5). I insert ```pdb.set_trace()``` here and CSRF token is actually passed to the backend as ```request_csrf_token```, but the token doesn't match for some reason. Can you also check the value to see if the token is really missing, or it's sent but doesn't match? Thanks. **Update:** Comparing to a successful uploading, I found ng2-file-upload missing salted csrf token in Request-Payload: ``` ------WebKitFormBoundary Content-Disposition: form-data; name="csrfmiddlewaretoken" <SALTED_CSRFTOKEN> ```
keeper commented 2017-02-10 16:43:50 +00:00 (Migrated from github.com)

@TheAn4rch1st
Hi, I finally figure how to make it works. According to Django document: https://docs.djangoproject.com/en/1.10/ref/csrf/#ajax
You have to add 'X-CSRFTOKEN' to the header like this:

this.uploader = new FileUploader(
{
  url: this.URL,
  headers: <Headers[]> [
    {
      name: 'X-CSRFTOKEN', value: this.csrftoken
    },
  ]
});
@TheAn4rch1st Hi, I finally figure how to make it works. According to Django document: https://docs.djangoproject.com/en/1.10/ref/csrf/#ajax You have to add 'X-CSRFTOKEN' to the header like this: ``` this.uploader = new FileUploader( { url: this.URL, headers: <Headers[]> [ { name: 'X-CSRFTOKEN', value: this.csrftoken }, ] }); ```
jacobdenobel commented 2017-02-10 17:03:51 +00:00 (Migrated from github.com)

@keeper I've fixed the problem. The weird thing thing was that I was recieving the token in my backend correctly, but for some reason it still wasn't authenticating right.

This fixed it for me:
this._uploader = new FileUploader(
{
url: this._URL,
headers: [{name: 'X-CSRFToken', value: csrfToken.value}]
});

@keeper I've fixed the problem. The weird thing thing was that I was recieving the token in my backend correctly, but for some reason it still wasn't authenticating right. This fixed it for me: this._uploader = new FileUploader( { url: this._URL, headers: [{name: 'X-CSRFToken', value: csrfToken.value}] });
jacobdenobel commented 2017-02-10 17:05:13 +00:00 (Migrated from github.com)

Haha lol

Haha lol
grapemix commented 2017-02-12 07:09:52 +00:00 (Migrated from github.com)

i used drf. There has few python oauth pkg.

To me, using header is overkill, but if it works for you, then it is cool. It seems you guys is likely to be blocked by the sever side oauth setup instead of the client side.

i used drf. There has few python oauth pkg. To me, using header is overkill, but if it works for you, then it is cool. It seems you guys is likely to be blocked by the sever side oauth setup instead of the client side.
moonlight824 commented 2017-05-09 09:02:32 +00:00 (Migrated from github.com)

@keeper
While, how can i get the value of 'this.csrftoken'?

@keeper While, how can i get the value of 'this.csrftoken'?
keeper commented 2017-05-09 09:14:58 +00:00 (Migrated from github.com)

@lqm229026
I cannot find the exact StackOverflow page I referenced, however I get it from cookie using:

  getCookie(name: string): string {
    var value = "; " + document.cookie;
    var parts = value.split("; " + name + "=");
    if (parts.length == 2) return decodeURIComponent(parts.pop().split(";").shift());
  }

then:

this.csrftoken = this.getCookie("csrftoken");

Mind you I'm pretty new to front-end and JS, and I'm not sure if this the best practice or even the right way to do it. Wish it would help.

@lqm229026 I cannot find the exact StackOverflow page I referenced, however I get it from cookie using: ``` getCookie(name: string): string { var value = "; " + document.cookie; var parts = value.split("; " + name + "="); if (parts.length == 2) return decodeURIComponent(parts.pop().split(";").shift()); } ``` then: ``` this.csrftoken = this.getCookie("csrftoken"); ``` Mind you I'm pretty new to front-end and JS, and I'm not sure if this the best practice or even the right way to do it. Wish it would help.
tarmo-randma commented 2017-12-07 14:04:21 +00:00 (Migrated from github.com)

It is also possible to update the CSRF token per request. Eg. you can do in your component constructor:

this.uploader = new FileUploader({ url: URL });
this.uploader.onBeforeUploadItem = (fileItem) => {
    fileItem.headers.push({name: 'X-XSRF-TOKEN', value: cookieService.getCookie('XSRF-TOKEN')});
    return fileItem;
};
It is also possible to update the CSRF token per request. Eg. you can do in your component constructor: this.uploader = new FileUploader({ url: URL }); this.uploader.onBeforeUploadItem = (fileItem) => { fileItem.headers.push({name: 'X-XSRF-TOKEN', value: cookieService.getCookie('XSRF-TOKEN')}); return fileItem; };
nikhiltiware commented 2018-02-07 15:29:41 +00:00 (Migrated from github.com)

@tarmo-randma which cookieService are you referring to?

@tarmo-randma which cookieService are you referring to?
tarmo-randma commented 2018-02-08 07:55:44 +00:00 (Migrated from github.com)

It is just a service I have created myself for accessing Cookie values - that is where I store the server provided XSRF token. keeper provided an example implementation already above. In my case I am using:

public getCookie(name: string) {
    let ca: Array<string> = document.cookie.split(';');
    let caLen: number = ca.length;
    let cookieName = name + "=";
    let c: string;

    for (let i: number = 0; i < caLen; i += 1) {
		c = ca[i].replace(/^\s+/g, "");
		if (c.indexOf(cookieName) == 0) {
			return c.substring(cookieName.length, c.length).trim();
		}
    }
    return "";
}
It is just a service I have created myself for accessing Cookie values - that is where I store the server provided XSRF token. keeper provided an example implementation already above. In my case I am using: public getCookie(name: string) { let ca: Array<string> = document.cookie.split(';'); let caLen: number = ca.length; let cookieName = name + "="; let c: string; for (let i: number = 0; i < caLen; i += 1) { c = ca[i].replace(/^\s+/g, ""); if (c.indexOf(cookieName) == 0) { return c.substring(cookieName.length, c.length).trim(); } } return ""; }
xfh commented 2018-03-08 16:23:52 +00:00 (Migrated from github.com)

In case you are using the HttpClientXsrfModule to add an XSRF Header, there is a simpler solution to get the XSRF Token.

Simply inject HttpXsrfTokenExtractor from '@angular/common/http'. To get the token call
const token = this.httpXsrfTokenExtractor.getToken();

In case you are using the HttpClientXsrfModule to add an XSRF Header, there is a simpler solution to get the XSRF Token. Simply inject HttpXsrfTokenExtractor from '@angular/common/http'. To get the token call `const token = this.httpXsrfTokenExtractor.getToken();`
alexis-landrieu-avanade commented 2018-11-22 08:49:07 +00:00 (Migrated from github.com)

In case you are using the HttpClientXsrfModule to add an XSRF Header, there is a simpler solution to get the XSRF Token.

Simply inject HttpXsrfTokenExtractor from '@angular/common/http'. To get the token call
const token = this.httpXsrfTokenExtractor.getToken();

The full code could be :

import { FileUploader, FileUploaderOptions } from 'ng2-file-upload/ng2-file-upload';
import { HttpXsrfTokenExtractor } from '@angular/common/http';
...
  constructor(private xsrfService: HttpXsrfTokenExtractor) {
    this.uploader = new FileUploader({ url: url });
    this.uploader.options.headers = [
      { name: 'X-XSRF-TOKEN', value: this.xsrfService.getToken() }
    ];
  }
> In case you are using the HttpClientXsrfModule to add an XSRF Header, there is a simpler solution to get the XSRF Token. > > Simply inject HttpXsrfTokenExtractor from '@angular/common/http'. To get the token call > `const token = this.httpXsrfTokenExtractor.getToken();` The full code could be : ```typescript import { FileUploader, FileUploaderOptions } from 'ng2-file-upload/ng2-file-upload'; import { HttpXsrfTokenExtractor } from '@angular/common/http'; ... constructor(private xsrfService: HttpXsrfTokenExtractor) { this.uploader = new FileUploader({ url: url }); this.uploader.options.headers = [ { name: 'X-XSRF-TOKEN', value: this.xsrfService.getToken() } ]; } ```
marcoshmendes commented 2019-02-21 18:22:10 +00:00 (Migrated from github.com)
Solved my problem: https://github.com/valor-software/ng2-file-upload/issues/1016#issuecomment-399444051
Yuer-1008 commented 2019-03-03 01:42:10 +00:00 (Migrated from github.com)

note the 'django.middleware.csrf.CsrfViewMiddleware' in the setting.py (MIDDLEWARE)

note the 'django.middleware.csrf.CsrfViewMiddleware' in the setting.py (MIDDLEWARE)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dc/ng2-file-upload#585