62
This Q&A is from 2016, and unsurprisingly I believe things have changed. The answer continues to receive upvotes, so I’m going to add in new information from other answers but leave the original answers as well.
Let me know in the comments which solution works for you.
Option 1. Set the default headers
In the file where you’re importing Axios, set the default headers:
import axios from 'axios';
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";
Option 2. Add it manually to the Axios call
Let’s say you’ve got the value of the token stored in a variable called csrfToken
. Set the headers in your axios call:
// ...
method: 'post',
url: '/api/data',
data: {...},
headers: {"X-CSRFToken": csrfToken},
// ...
Option 3. Setting xsrfHeaderName
in the call:
Add this:
// ...
method: 'post',
url: '/api/data',
data: {...},
xsrfHeaderName: "X-CSRFToken",
// ...
Then in your settings.py
file, add this line:
CSRF_COOKIE_NAME = "XSRF-TOKEN"
Edit (June 10, 2017): User @yestema says that it works slightly different with Safari[2]
Edit (April 17, 2019): User @GregHolst says that the Safari solution above does not work for him. Instead, he used the above Solution #3 for Safari 12.1 on MacOS Mojave. (from comments)
Edit (February 17, 2019): You might also need to set[3]:
axios.defaults.withCredentials = true
Things I tried that didn’t work: 1
24
I’ve found out, that axios.defaults.xsrfCookieName = "XCSRF-TOKEN";
and CSRF_COOKIE_NAME = "XCSRF-TOKEN"
DOESN’T WORK IN APPLE Safari on Mac OS
The solution for MAC Safari is easy, just change XCSRF-TOKEN
to csrftoken
So, in js-code should be:
import axios from 'axios';
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";
In settings.py:
CSRF_COOKIE_NAME = "csrftoken"
- [Django]-How to resolve "django.core.exceptions.ImproperlyConfigured: Application labels aren't unique, duplicates: foo" in Django 1.7?
- [Django]-How do I run tests for all my Django apps only?
- [Django]-Update only specific fields in a models.Model
15
This configuration works for me without problems Config axios CSRF django
import axios from 'axios'
/**
* Config global for axios/django
*/
axios.defaults.xsrfHeaderName = "X-CSRFToken"
axios.defaults.xsrfCookieName = 'csrftoken'
export default axios
- [Django]-Django: Error: You don't have permission to access that port
- [Django]-Django download a file
- [Django]-Django connection to postgres by docker-compose
8
After spending too many hours researching, and implementing the above answer, I found my error for this problem! I have added this answer to be supplemental of the accepted answer. I had set up everything as mentioned, but the gotcha for me was actually in the browser itself!
If testing locally, make sure you are accessing react through 127.0.0.1
instead of localhost
! localhost
handles request headers differently and doesn’t show the CSRF tokens in the header response, where as 127.0.0.1
will! So instead of localhost:3000
try 127.0.0.1:3000
!
Hope this helps.
- [Django]-Substring in a django template?
- [Django]-How do I install an old version of Django on virtualenv?
- [Django]-Celery missed heartbeat (on_node_lost)
5
The “easy way” almost worked for me. This seems to work:
import axios from 'axios';
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "XCSRF-TOKEN";
And in the settings.py file:
CSRF_COOKIE_NAME = "XCSRF-TOKEN"
- [Django]-Where should signal handlers live in a django project?
- [Django]-Django ORM – objects.filter() vs. objects.all().filter() – which one is preferred?
- [Django]-Celery – Get task id for current task
2
You could add the Django-provided CSRF token manually into all of your post requests, but that’s annoying.
From the Django docs:
While the above method (manually setting CSRF token) can be used for AJAX POST requests, it has some inconveniences: you have to remember to pass the CSRF token in as POST data with every POST request. For this reason, there is an alternative method: on each XMLHttpRequest, set a custom X-CSRFToken header to the value of the CSRF token. This is often easier, because many JavaScript frameworks provide hooks that allow headers to be set on every request.
The docs have code you can use to pull the CSRF token from the CSRF token cookie and then add it to the header of your AJAX request.
- [Django]-Redirect / return to same (previous) page in Django?
- [Django]-Django.db.utils.IntegrityError: duplicate key value violates unique constraint "django_migrations_pkey"
- [Django]-Django Many-to-Many (m2m) Relation to same model
2
There is actually a really easy way to do this.
Add axios.defaults.xsrfHeaderName = "X-CSRFToken";
to your app config and then set CSRF_COOKIE_NAME = "XSRF-TOKEN"
in your settings.py file. Works like a charm.
- [Django]-Django: what is the difference (rel & field)
- [Django]-Add rich text format functionality to django TextField
- [Django]-How to automatically login a user after registration in django
1
For me, django wasn’t listening to the headers that I was sending. I could curl into the api but couldn’t access it with axios. Check out the cors-headers package… it might be your new best friend.
I fixed it by installing django-cors-headers
pip install django-cors-headers
And then adding
INSTALLED_APPS = (
...
'corsheaders',
...
)
and
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
into my settings.py
I also had
ALLOWED_HOSTS = ['*']
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CORS_EXPOSE_HEADERS = (
'Access-Control-Allow-Origin: *',
)
in my settings.py although that is probably overkill
- [Django]-Add Text on Image using PIL
- [Django]-Is it possible to pass query parameters via Django's {% url %} template tag?
- [Django]-How to POST a django form with AJAX & jQuery
1
In addition to what yestema said (and echoed by krescruz, cran_man, Dave Merwin et. al), You also need:
axios.defaults.withCredentials = true
- [Django]-Django request to find previous referrer
- [Django]-How do I go straight to template, in Django's urls.py?
- [Django]-Django: Why do some model fields clash with each other?