Comment puis-je activer CORS sur Django REST Framework


Réponses:


145

Le lien que vous avez référencé dans votre question recommande d'utiliser django-cors-headers, dont la documentation dit d'installer la bibliothèque

pip install django-cors-headers

puis ajoutez-le à vos applications installées:

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

Vous devrez également ajouter une classe middleware pour écouter les réponses:

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

Veuillez parcourir la section configuration de sa documentation, en portant une attention particulière aux différents CORS_ORIGIN_paramètres. Vous devrez en définir certains en fonction de vos besoins.


2
connaissez-vous un autre moyen de le faire, sans avoir besoin d'installer une nouvelle dépendance? J'essaye de créer une classe middleware maintenant
— Julio Marins

5
@JulioMarins, pourquoi écririez-vous votre propre version alors qu'elle est facilement disponible et facilement installable, avec 12 versions, 21 contributeurs, plus de 800 étoiles et plus de 100 fourchettes?
— Chris

2
Vous avez un point en effet, mais comme le seul besoin d'un simple CORS est un en-tête, Access-Control-Allow-Origin: *je ne vois pas pourquoi charger un tout, je vais mettre une autre façon de le faire dans votre réponse afin que les deux méthodes puissent être disponibles. référence: [link (] enable-cors.org/server.html )
— Julio Marins

2
@JulioMarins, ce serait l'approche du marteau. Si vous regardez le lien de configuration que j'ai fourni, vous verrez qu'il django-cors-headersest beaucoup plus flexible que cela. Si vous préférez créer votre propre classe, soyez mon invité. Mais j'utiliserais cette bibliothèque.
— Chris

4
@Chris Je pense que vous devriez ajouter CORS_ORIGIN_WHITELIST afin de mettre en liste blanche l'hôte appelant.
— Hakim

58
pip install django-cors-headers

puis ajoutez-le à vos applications installées:

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

Vous devrez également ajouter une classe middleware pour écouter les réponses:

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',
]

plus de détails: https://github.com/ottoyiu/django-cors-headers/#configuration

lire la documentation officielle peut résoudre presque tous les problèmes


4
L'ajout des quatre lignes que vous avez ajoutées à la réponse de @ Chris était nécessaire pour que cela fonctionne pour moi.
— Matt D

5
Pourquoi est CORS_ORIGIN_ALLOW_ALL = True, mais CORS_ORIGIN_WHITELISTest toujours défini? La documentation semble donner l'impression que cela n'est pas nécessaire et semble déroutant pour la réponse ici.
— phoenix

CORS_ORIGIN_ALLOW_ALL Si True, la liste blanche ne sera pas utilisée et toutes les origines seront acceptées.
— BjornW

2
Gardez également à l'esprit 'corsheaders.middleware.CorsMiddleware',qu'il faut plutôt être en haut de la liste, sinon la connexion peut être rejetée avant d'y accéder.
— Sebastián Vansteenkiste

14

Vous pouvez le faire en utilisant un middleware personnalisé, même en sachant que la meilleure option consiste à utiliser l'approche testée du package django-cors-headers. Cela dit, voici la solution:

créez la structure et les fichiers suivants:

- 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

ajouter à settings.pyla ligne marquée:

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
)

Merci Julio! Votre code middleware doit être mis à jour avec l'exemple de code @masnun. De plus, l'importation ne fonctionne pas pour moi, l'importation depuis. corrige le problème: from . import corsMiddleware
— Pavel Daynyak

12

Au cas où quelqu'un reviendrait à cette question et déciderait d'écrire son propre middleware, ceci est un exemple de code pour le nouveau middleware de style 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

7

Pour les versions Django> 1.10, selon la documentation , un MIDDLEWARE personnalisé peut être écrit en tant que fonction, disons dans le fichier: yourproject/middleware.py(en tant que frère 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

et enfin, ajoutez le chemin python de cette fonction (à la racine de votre projet) à la liste MIDDLEWARE de votre projet settings.py:

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

Peasy facile!


L'approche publiée précédemment utilise MIDDLEWARE_CLASSES et non MIDDLEWARE. Cette technique fonctionne, donc le vote négatif n'était pas demandé :) @JulioMarins
— Dhruv Batheja

1
mec, la solution est la même. Vous discutez de l'implémentation sur la version Django. Votre code est également avec une indentation incorrecte open_access_middleware.
— Julio Marins

4

Eh bien, je ne connais pas les gars mais:

en utilisant ici python 3.6 et django 2.2

Renommer MIDDLEWARE_CLASSES en MIDDLEWARE dans settings.py a fonctionné.


3

Voici les étapes de travail sans avoir besoin de modules externes:

Étape 1: Créez un module dans votre application.

Par exemple, supposons que nous ayons une application appelée user_registration_app . Explorez user_registration_app et créez un nouveau fichier.

Appelons cela comme custom_cors_middleware.py

Collez la définition de classe ci-dessous:

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

Étape 2: enregistrer un middleware

Dans votre fichier settings.py, ajoutez cette ligne

'user_registration_app.custom_cors_middleware.CustomCorsMiddleware'

Par exemple:

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

    ]

N'oubliez pas de remplacer user_registration_app par le nom de votre application sur laquelle vous avez créé votre module custom_cors_middleware.py.

Vous pouvez maintenant vérifier qu'il ajoutera les en-têtes de réponse requis à toutes les vues du projet!


0

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

Suivre les instructions officielles ne fonctionne pas

Enfin, utilisez l'ancienne méthode pour le comprendre.

AJOUTER:

# 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',
    ),
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.