112👍
Django and AngularJS both have CSRF support already, your part is quite simple.
First, you need to enable CSRF in Django, I believe you have already done so, if not, follow Django doc https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax.
Now, Django will set a cookie named csrftoken
on the first GET request and expects a custom HTTP header X-CSRFToken
on later POST/PUT/DELETE requests.
For Angular, it expects the cookie named XSRF-TOKEN
and will do POST/PUT/DELETE requests with X-XSRF-TOKEN
header, so you need to do a little bit tweak to make the two go with each other:
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
Add above two lines somewhere in your js code, module.config() block is a good place for this.
That’s it.
NOTE: This is for angular 1.1.5, older versions might need different approach.
Update:
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.
60👍
var foo = angular.module('foo', ['bar']);
foo.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);
And all modules services and controllers, where $http used, will send requests with csrf token.
- [Django]-Django-allauth social account connect to existing account on login
- [Django]-When should I use a custom Manager versus a custom QuerySet in Django?
- [Django]-How to access the local Django webserver from outside world
11👍
After searching around, what worked for me was from this post with the following code:
angular.module( '[your module name]',
... [some dependencies] ...
'ngCookies',
... [other dependencies] ...
)
.run( function run( $http, $cookies ){
// For CSRF token compatibility with Django
$http.defaults.headers.post['X-CSRFToken'] = $cookies.get('csrftoken');
})
This is of course after getting the cookie through a GET request from the django server.
I also looked into some of the other answers here, including Ye Liun’s but couldn’t find anything in the official docs specifying changes to the defaults options for xsrf on $httpProvider, other than this pull request which didn’t work for me at the time of me writing this post.
- [Django]-Is it bad to have my virtualenv directory inside my git repository?
- [Django]-Django REST Framework – Separate permissions per methods
- [Django]-How to merge consecutive database migrations in django 1.9+?
1👍
I created a Django App for my AngularJS app, in the same Django project as my (REST) API Django App, that only serves the index.html file (which is just a sym.link). In this way the CSRF Cookie is set without an additional GET request.
Please see my answer here about AngularJS Single Page Web Application on Sub-domain A talking to a Django JSON (REST) API on Sub-domain B using CORS and CSRF protection
- [Django]-How to update an existing Conda environment with a .yml file
- [Django]-Django: Error: You don't have permission to access that port
- [Django]-Identify the changed fields in django post_save signal
0👍
If you have your cookies set to disallow javascript access, you need to do the following. In your template, before creating the django app, add this:
<script>
window.csrf_token = "{{ csrf_token }}";
</script>
In your angular app, add this:
angularApp.config(["$httpProvider", function($httpProvider) {
$httpProvider.defaults.headers.common["X-CSRFToken"] = window.csrf_token;
}]);
At least through Django 1.9, the CSRF token does not change with each request. It only changes when a user logs in. If you are doing a single page angular app, you need to make sure you reset the token on login/logout and this should work fine.
NOTE: This does not currently work in Django 1.10 or later due to the CSRF token changing on each request. See Pass Django CSRF token to Angular with CSRF_COOKIE_HTTPONLY
- [Django]-How do I do a not equal in Django queryset filtering?
- [Django]-Django: how save bytes object to models.FileField?
- [Django]-Referencing multiple submit buttons in django