javascript - framework - integrar angularjs con django
Django csrf token+Angularjs (5)
Tengo django corriendo en un servidor apache usando mod_wsgi, así como una aplicación angularjs servida directamente por apache, no por django. Me gustaría hacer llamadas POST al servidor django (ejecutando rest_framework) pero estoy teniendo problemas con el token csrf.
¿Hay alguna forma de configurar el token desde el servidor sin poner {% csrf token %}
como parte de la plantilla (ya que estas páginas no pasan por django)?
- Me gustaría poder obtener un token csrf a través de una solicitud GET como una cookie.
- Me gustaría poder realizar solicitudes POST al servidor django con el valor de la cookie csrf token.
Creé una aplicación Django para mi aplicación AngularJS, en el mismo proyecto Django que mi API (REST), la aplicación Django, que solo sirve para el archivo index.html (que es solo un enlace simbólico). De esta forma, la cookie CSRF se configura sin una solicitud GET adicional.
Consulte mi respuesta aquí sobre la aplicación web de una sola página de AngularJS en el subdominio A hablando con una API de Django JSON (REST) en el subdominio B utilizando la protección CORS y CSRF
Después de buscar, lo que funcionó para mí fue esta publicación con el siguiente código:
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'');
})
Esto es, por supuesto, después de obtener la cookie a través de una solicitud GET del servidor django.
También busqué algunas de las otras respuestas aquí, incluida la de Ye Liun, pero no pude encontrar nada en los documentos oficiales que especificaran cambios a las opciones predeterminadas para xsrf en $ httpProvider, aparte de esta solicitud de extracción que no me sirvió en el tiempo de escribir esta publicación.
Django y AngularJS ya tienen soporte CSRF, su parte es bastante simple.
Primero, necesita habilitar CSRF en Django, creo que ya lo ha hecho, si no, siga Django doc https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax .
Ahora, Django configurará una cookie llamada csrftoken
en la primera solicitud GET y espera un encabezado HTTP personalizado X-CSRFToken
en solicitudes POST / PUT / DELETE posteriores.
Para Angular, espera que la cookie se llame XSRF-TOKEN
y haga las solicitudes POST / PUT / DELETE con el encabezado X-XSRF-TOKEN
, por lo que debe hacer un pequeño ajuste para hacer que las dos funcionen entre sí:
$httpProvider.defaults.xsrfCookieName = ''csrftoken'';
$httpProvider.defaults.xsrfHeaderName = ''X-CSRFToken'';
Agregue las dos líneas anteriores en algún lugar de su código js, el bloque module.config () es un buen lugar para esto.
Eso es.
NOTA: Esto es para angular 1.1.5, las versiones anteriores pueden necesitar un enfoque diferente.
Actualizar:
Dado que la aplicación angular no está servida por django, para permitir que se establezca la cookie, la aplicación angular debe primero hacer una solicitud GET a django.
Si tiene las cookies configuradas para no permitir el acceso a JavaScript, debe hacer lo siguiente. En su plantilla, antes de crear la aplicación django, agregue esto:
<script>
window.csrf_token = "{{ csrf_token }}";
</script>
En su aplicación angular, agregue esto:
angularApp.config(["$httpProvider", function($httpProvider) {
$httpProvider.defaults.headers.common["X-CSRFToken"] = window.csrf_token;
}]);
Al menos a través de Django 1.9, el token CSRF no cambia con cada solicitud. Solo cambia cuando un usuario inicia sesión. Si está haciendo una aplicación de una sola página angular, debe asegurarse de restablecer el token al iniciar / cerrar sesión, y esto debería funcionar bien.
NOTA: Esto actualmente no funciona en Django 1.10 o posterior debido al cambio de token CSRF en cada solicitud. Consulte Pase el token de Django CSRF a Angular con CSRF_COOKIE_HTTPONLY
var foo = angular.module(''foo'', [''bar'']);
foo.config([''$httpProvider'', function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = ''csrftoken'';
$httpProvider.defaults.xsrfHeaderName = ''X-CSRFToken'';
}]);
Y todos los servicios y controladores de módulos, donde se utiliza $ http, enviarán solicitudes con token csrf.