¿Cómo puedo habilitar CORS en Django REST Framework?

Respuestas:

147

El enlace al que hizo referencia en su pregunta recomienda usar django-cors-headers, cuya documentación dice que instale la biblioteca

pip install django-cors-headers

y luego agréguelo a sus aplicaciones instaladas:

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

También deberá agregar una clase de middleware para escuchar las respuestas:

MIDDLEWARE_CLASSES = (
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
)

Examine la sección de configuración de su documentación, prestando especial atención a las distintas CORS_ORIGIN_configuraciones. Deberá configurar algunos de ellos según sus necesidades.

Chris
fuente
2
¿Conoce alguna otra forma de hacerlo, sin la necesidad de instalar una nueva dependencia? Estoy tratando de crear una clase de middleware ahora
Julio Marins
5
@JulioMarins, ¿por qué escribirías tu propia versión cuando está disponible y se puede instalar fácilmente, con 12 lanzamientos, 21 colaboradores, más de 800 estrellas y más de 100 bifurcaciones?
Chris
2
De hecho, tiene un punto, pero dado que la única necesidad de un CORS simple es un encabezado Access-Control-Allow-Origin: *, no veo por qué cargar todo, pondré otra forma de hacer esto en su respuesta para que ambos métodos puedan estar disponibles. referencia: [link (] enable-cors.org/server.html )
Julio Marins
2
@JulioMarins, ese sería el enfoque de mazo. Si observa el enlace de configuración que le proporcioné, verá que django-cors-headerses mucho más flexible que eso. Si prefiere crear su propia clase, sea mi invitado. Pero estaría usando esa biblioteca.
Chris
4
@Chris Creo que deberías agregar CORS_ORIGIN_WHITELIST para que incluyas en la lista blanca el host que llama.
Hakim
58
pip install django-cors-headers

y luego agréguelo a sus aplicaciones instaladas:

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

También deberá agregar una clase de middleware para escuchar las respuestas:

MIDDLEWARE_CLASSES = (
    ...
    'corsheaders.middleware.CorsMiddleware',  
    'django.middleware.common.CommonMiddleware',  
    ...
)

CORS_ORIGIN_ALLOW_ALL = True # If this is used then `CORS_ORIGIN_WHITELIST` will not have any effect
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = [
    'http://localhost:3030',
] # If this is used, then not need to use `CORS_ORIGIN_ALLOW_ALL = True`
CORS_ORIGIN_REGEX_WHITELIST = [
    'http://localhost:3030',
]

más detalles: https://github.com/ottoyiu/django-cors-headers/#configuration

leer la documentación oficial puede resolver casi todos los problemas

likaiguo.happy
fuente
4
Agregar las cuatro líneas que agregó a la respuesta de @ Chris fue necesario para que esto funcione para mí.
Matt D
5
¿Por qué está CORS_ORIGIN_ALLOW_ALL = True, pero CORS_ORIGIN_WHITELISTtodavía está establecido? Los documentos parecen hacer que parezca que esto no es necesario y parece ser confuso para la respuesta aquí.
Phoenix,
CORS_ORIGIN_ALLOW_ALL Si es True, la lista blanca no se utilizará y se aceptarán todos los orígenes.
BjornW
2
También tenga en cuenta que 'corsheaders.middleware.CorsMiddleware',debe estar en la parte superior de la lista, de lo contrario, la conexión puede rechazarse antes de acceder a ella.
Sebastián Vansteenkiste
14

Puede hacerlo mediante el uso de un middleware personalizado, aunque sepa que la mejor opción es utilizar el enfoque probado del paquete django-cors-headers. Dicho esto, aquí está la solución:

cree la siguiente estructura y archivos:

- myapp/middleware/__init__.py

from corsMiddleware import corsMiddleware

- myapp/middleware/corsMiddleware.py

class corsMiddleware(object):
    def process_response(self, req, resp):
        resp["Access-Control-Allow-Origin"] = "*"
        return resp

agregar a settings.pyla línea marcada:

MIDDLEWARE_CLASSES = (
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",

    # Now we add here our custom middleware
     'app_name.middleware.corsMiddleware' <---- this line
)
Julio Marins
fuente
¡Gracias Julio! Su código de middleware debe actualizarse con la muestra de código @masnun. Además, la importación no me funciona, importando desde. soluciona el problema: from . import corsMiddleware
Pavel Daynyak
13

En caso de que alguien vuelva a esta pregunta y decida escribir su propio middleware, esta es una muestra de código para el nuevo estilo de middleware de Django:

class CORSMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        response["Access-Control-Allow-Origin"] = "*"

        return response
masnun
fuente
7

Para las versiones de Django> 1.10, de acuerdo con la documentación , se puede escribir un MIDDLEWARE personalizado como una función, digamos en el archivo: yourproject/middleware.py(como hermano de settings.py):

def open_access_middleware(get_response):
    def middleware(request):
        response = get_response(request)
        response["Access-Control-Allow-Origin"] = "*"
        response["Access-Control-Allow-Headers"] = "*"
        return response
    return middleware

y finalmente, agregue la ruta de Python de esta función (escriba la raíz de su proyecto) a la lista MIDDLEWARE en su proyecto settings.py:

MIDDLEWARE = [
  .
  .
  'django.middleware.clickjacking.XFrameOptionsMiddleware',
  'yourproject.middleware.open_access_middleware'
]

¡Pan comido!

Dhruv Batheja
fuente
El enfoque publicado antes usa MIDDLEWARE_CLASSES y no MIDDLEWARE. Esta técnica funciona, por lo que el voto negativo fue injustificado :) @JulioMarins
Dhruv Batheja
1
amigo, la solución es la misma. Estás discutiendo sobre la implementación en la versión de Django. Su código también tiene una sangría incorrecta open_access_middleware.
Julio Marins
4

Bueno, no conozco chicos pero:

usando aquí python 3.6 y django 2.2

Cambiar el nombre de MIDDLEWARE_CLASSES a MIDDLEWARE en settings.py funcionó.

jnowak
fuente
3

A continuación se muestran los pasos de trabajo sin la necesidad de ningún módulo externo:

Paso 1: crea un módulo en tu aplicación.

Por ejemplo, supongamos que tenemos una aplicación llamada user_registration_app . Explore user_registration_app y cree un nuevo archivo.

Llamemos a esto como custom_cors_middleware.py

Pegue la siguiente definición de clase:

class CustomCorsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)
        response["Access-Control-Allow-Origin"] = "*"
        response["Access-Control-Allow-Headers"] = "*"

        # Code to be executed for each request/response after
        # the view is called.

        return response

Paso 2: registrar un middleware

En el archivo settings.py de su proyecto, agregue esta línea

'user_registration_app.custom_cors_middleware.CustomCorsMiddleware'

P.ej:

  MIDDLEWARE = [
        'user_registration_app.custom_cors_middleware.CustomCorsMiddleware', # ADD THIS LINE BEFORE CommonMiddleware
         ...
        'django.middleware.common.CommonMiddleware',

    ]

Recuerde reemplazar user_registration_app con el nombre de su aplicación donde ha creado su módulo custom_cors_middleware.py.

¡Ahora puede verificar que agregará los encabezados de respuesta requeridos a todas las vistas en el proyecto!

usuario3785966
fuente
0

Django = 2.2.12 django-cors-headers = 3.2.1 djangorestframework = 3.11.0

Seguir las instrucciones oficiales no funciona

Finalmente, usa la forma antigua para resolverlo.

AÑADIR:

# proj/middlewares.py
from rest_framework.authentication import SessionAuthentication


class CsrfExemptSessionAuthentication(SessionAuthentication):

    def enforce_csrf(self, request):
        return  # To not perform the csrf check previously happening
#proj/settings.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'proj.middlewares.CsrfExemptSessionAuthentication',
    ),
}
CK
fuente