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.

Chris
la source
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

likaiguo.happy
la source
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
)
Julio Marins
la source
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
Masnun
la source
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!

Dhruv Batheja
la source
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é.

jnowak
la source
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!

user3785966
la source
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',
    ),
}
CK
la source