instalar - Django Rest Framework eliminar csrf
django rest framework with django 2 (10)
Esto también podría ser un problema durante un ataque DNS Rebinding .
Entre los cambios de DNS, esto también puede ser un factor. Esperar hasta que DNS esté completamente descargado resolverá esto si estaba funcionando antes de problemas / cambios de DNS.
Sé que hay respuestas con respecto a Django Rest Framework, pero no pude encontrar una solución a mi problema.
Tengo una aplicación que tiene autenticación y alguna funcionalidad. Le agregué una nueva aplicación, que usa Django Rest Framework. Quiero usar la biblioteca solo en esta aplicación. También quiero hacer una solicitud POST, y siempre recibo esta respuesta:
{
"detail": "CSRF Failed: CSRF token missing or incorrect."
}
Tengo el siguiente código:
# urls.py
from django.conf.urls import patterns, url
urlpatterns = patterns(
''api.views'',
url(r''^object/$'', views.Object.as_view()),
)
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from django.views.decorators.csrf import csrf_exempt
class Object(APIView):
@csrf_exempt
def post(self, request, format=None):
return Response({''received data'': request.data})
Quiero agregar la API sin afectar la aplicación actual. Entonces, mi pregunta es ¿cómo puedo desactivar CSRF solo para esta aplicación?
Intenté algunas de las respuestas anteriores y sentí que crear una clase separada era un poco exagerado.
Como referencia, me encontré con este problema al intentar actualizar un método de vista basado en funciones a un método de vista basado en clases para el registro de usuarios.
Cuando utilice vistas basadas en clases (CBV) y Django Rest Framework (DRF), herede de la clase ApiView y establezca permisos_clases y autenticación_clases en una tupla vacía. Encuentra un ejemplo a continuación.
class DisableCSRF(object):
def process_request(self, request):
setattr(request, ''_dont_enforce_csrf_checks'', True)
Me llama la atención el mismo problema. Seguí esta reference y funcionó. La solución es crear un middleware
Agregue el archivo disable.py en una de sus aplicaciones (en mi caso es ''myapp'')
MIDDLEWARE_CLASSES = (
myapp.disable.DisableCSRF,
)
Y agregue el middileware a MIDDLEWARE_CLASSES
self.enforce_csrf(request)
Mi solución se muestra golpe. Solo decora mi clase.
class UserRegistrationView(APIView):
permission_classes = ()
authentication_classes = ()
def post(self, request, *args, **kwargs):
# rest of your code here
Modificar urls.py
Si administra sus rutas en urls.py, puede ajustar sus rutas deseadas con csrf_exempt () para excluirlas del middleware de verificación CSRF.
from django.conf.urls import patterns, url
from django.views.decorators.csrf import csrf_exempt
import views
urlpatterns = patterns('''',
url(r''^object/$'', csrf_exempt(views.ObjectView.as_view())),
...
)
Alternativamente, como decorador, algunos pueden encontrar el uso del decorador @csrf_exempt más adecuado para sus necesidades
por ejemplo,
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
@csrf_exempt
def my_view(request):
return HttpResponse(''Hello world'')
debe hacer el trabajo!
Para todos los que no encontraron una respuesta útil.
Sí, DRF elimina automáticamente la protección CSRF si no utiliza la CLASE
SessionAuthentication
AUTENTICACIÓN de autenticación de
SessionAuthentication
, por ejemplo, muchos desarrolladores usan solo JWT:
''DEFAULT_AUTHENTICATION_CLASSES'': (
''rest_framework_jwt.authentication.JSONWebTokenAuthentication'',
),
Pero el problema
CSRF not set
puede ocurrir por alguna otra razón, por ejemplo, no agregó correctamente la ruta a su vista:
url(r''^api/signup/'', CreateUserView), # <= error! DRF cant remove CSRF because it is not as_view that does it!
en lugar de
url(r''^api/signup/'', CreateUserView.as_view()),
Si está utilizando un entorno virtual exclusivo para su aplicación, puede utilizar el siguiente enfoque sin ninguna otra aplicación efectiva.
Lo que observó sucede porque
rest_framework/authentication.py
tiene este código en el método de
authenticate
de la clase
SessionAuthentication
:
if not request.csrf_exempt:
self.enforce_csrf(request)
Puede modificar la clase
Request
para que tenga una propiedad llamada
csrf_exempt
e inicializarla dentro de su clase View respectiva a
True
si no desea verificaciones CSRF.
Por ejemplo:
A continuación, modifique el código anterior de la siguiente manera:
from django.views.decorators.csrf import csrf_exempt
@method_decorator(csrf_exempt, name=''dispatch'')
@method_decorator(basic_auth_required(
target_test=lambda request: not request.user.is_authenticated
), name=''dispatch'')
class GenPedigreeView(View):
pass
Hay algunos cambios relacionados que tendría que hacer en la clase
Request
.
Una implementación completa está disponible aquí (con descripción completa):
https://github.com/piaxis/django-rest-framework/commit/1bdb872bac5345202e2f58728d0e7fad70dfd7ed
Si no desea utilizar la autenticación basada en sesión, puede eliminar la
Session Authentication
de REST_AUTHENTICATION_CLASSES y eso eliminaría automáticamente todos los problemas basados en csrf.
Pero en ese caso, las API navegables podrían no funcionar.
Además este error no debería venir incluso con la autenticación de sesión.
Debe usar autenticación personalizada como TokenAuthentication para sus apis y asegúrese de enviar
Accept:application/json
y
Content-Type:application/json
(siempre que esté usando json) en sus solicitudes junto con el token de autenticación.
Solución más fácil:
En views.py, use llaves CsrfExemptMixin y autenticación_clases:
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from django.views.decorators.csrf import csrf_exempt
from braces.views import CsrfExemptMixin
class Object(CsrfExemptMixin, APIView):
authentication_classes = []
def post(self, request, format=None):
return Response({''received data'': request.data})
¿Por qué está ocurriendo este error?
Esto sucede debido al esquema de
SessionAuthentication
predeterminado utilizado por DRF.
La
SessionAuthentication
de sesión de DRF utiliza el marco de sesión de Django para la autenticación que requiere que se verifique CSRF.
Cuando no define ninguna clase de
authentication_classes
en su vista / conjunto de vistas, DRF usa estas clases de autenticación como predeterminadas.
''DEFAULT_AUTHENTICATION_CLASSES''= (
''rest_framework.authentication.SessionAuthentication'',
''rest_framework.authentication.BasicAuthentication''
),
Dado que DRF necesita admitir autenticación basada en sesión y no basada en sesión para las mismas vistas, impone la verificación CSRF solo para usuarios autenticados. Esto significa que solo las solicitudes autenticadas requieren tokens CSRF y las solicitudes anónimas pueden enviarse sin tokens CSRF.
Si está utilizando una API de estilo AJAX con autenticación de sesión, deberá incluir un token CSRF válido para cualquier llamada de método HTTP "insegura", como solicitudes
PUT, PATCH, POST or DELETE
.
¿Qué hacer entonces?
Ahora, para deshabilitar la verificación csrf, puede crear una clase de autenticación personalizada
CsrfExemptSessionAuthentication
que se extiende desde la clase
SessionAuthentication
predeterminada.
En esta clase de autenticación,
enforce_csrf()
la
enforce_csrf()
que estaba ocurriendo dentro de la
SessionAuthentication
real.
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
class CsrfExemptSessionAuthentication(SessionAuthentication):
def enforce_csrf(self, request):
return # To not perform the csrf check previously happening
Desde su punto de vista, puede definir las
authentication_classes
de
authentication_classes
como:
authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication)
Esto debería manejar el error csrf.