javascript - formulaire - Django csrf jeton+Angularjs



formulaire dynamique django (4)

J'ai django fonctionnant sur un serveur apache en utilisant mod_wsgi, ainsi qu'une application angularjs servie directement par apache, pas par django. Je voudrais faire des appels POST au serveur django (en cours d'exécution rest_framework) mais j'ai des problèmes avec le jeton csrf.

Est-il possible de définir le jeton à partir du serveur sans mettre {% csrf token %} dans le modèle (puisque ces pages ne passent pas par django)?

  1. Je voudrais pouvoir obtenir un jeton csrf via une requête GET en tant que cookie.
  2. Je voudrais pouvoir ensuite faire des requêtes POST au serveur django avec la valeur de cookie jeton csrf.

Answer #1

Après avoir cherché autour de moi, ce qui a fonctionné pour moi était de ce post avec le code suivant:

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');
})

C'est bien sûr après avoir obtenu le cookie via une requête GET du serveur django.

J'ai également examiné certaines des autres réponses ici, y compris celle de Ye Liun, mais je n'ai rien trouvé dans les documents officiels spécifiant les changements aux options par défaut pour xsrf sur $ httpProvider, autre que cette requête de tirage qui n'a pas fonctionné pour moi au temps de moi écrire ce post.


Answer #2

Django et AngularJS ont déjà tous les deux un support CSRF, votre rôle est assez simple.

D'abord, vous devez activer le CSRF dans Django, je crois que vous l'avez déjà fait, sinon, suivez le doc Django https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax .

Maintenant, Django va définir un cookie nommé csrftoken sur la première requête GET et attend un en-tête HTTP personnalisé X-CSRFToken lors des X-CSRFToken POST / PUT / DELETE ultérieures.

Pour Angular, il attend le cookie nommé XSRF-TOKEN et fera les requêtes POST / PUT / DELETE avec l'en X-XSRF-TOKEN , donc vous devez faire un petit tweak pour que les deux X-XSRF-TOKEN :

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

Ajouter ci-dessus deux lignes quelque part dans votre code js, module.config () est un bon endroit pour cela.

C'est tout.

NOTE: Ceci est pour angulaire 1.1.5, les versions plus anciennes pourraient nécessiter une approche différente.

Mettre à jour:

Puisque l'application angulaire n'est pas servie par django, afin de laisser le cookie à définir, l'application angulaire doit d'abord faire une requête GET à django.


Answer #3

Si vos cookies sont configurés pour interdire l'accès javascript, vous devez procéder comme suit. Dans votre modèle, avant de créer l'application django, ajoutez ceci:

<script>
    window.csrf_token = "{{ csrf_token }}";
</script>

Dans votre application angulaire, ajoutez ceci:

angularApp.config(["$httpProvider", function($httpProvider) {
    $httpProvider.defaults.headers.common["X-CSRFToken"] = window.csrf_token;
}]);

Au moins via Django 1.9, le jeton CSRF ne change pas avec chaque requête. Il ne change que lorsqu'un utilisateur se connecte. Si vous réalisez une application angulaire sur une seule page, vous devez vous assurer de réinitialiser le jeton lors de la connexion / déconnexion et cela devrait fonctionner correctement.

Remarque: cela ne fonctionne pas actuellement dans Django 1.10 ou version ultérieure en raison de la modification du jeton CSRF sur chaque demande. Voir Passer le jeton CSRF Django à Angular avec CSRF_COOKIE_HTTPONLY


Answer #4
var foo = angular.module('foo', ['bar']);

foo.config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.xsrfCookieName = 'csrftoken';
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);

Et tous les services et contrôleurs de modules, où $ http est utilisé, enverront des requêtes avec le jeton csrf.





angularjs