Wie kann ich CORS auf dem Django REST Framework aktivieren?

Antworten:

139

Der Link, auf den Sie in Ihrer Frage verwiesen haben, empfiehlt die Verwendung django-cors-headers, in dessen Dokumentation die Installation der Bibliothek angegeben ist

pip install django-cors-headers

und fügen Sie es dann Ihren installierten Apps hinzu:

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

Sie müssen auch eine Middleware-Klasse hinzufügen, um die Antworten abzuhören:

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

Bitte durchsuchen Sie den Konfigurationsabschnitt der Dokumentation und achten Sie dabei besonders auf die verschiedenen CORS_ORIGIN_Einstellungen. Sie müssen einige davon basierend auf Ihren Anforderungen festlegen.

Chris
quelle
2
Kennen Sie einen anderen Weg, ohne eine neue Abhängigkeit installieren zu müssen? Ich versuche jetzt, eine Middleware-Klasse zu erstellen
Julio Marins
5
@ JulioMarins, warum sollten Sie Ihre eigene Version schreiben, wenn diese leicht verfügbar und leicht zu installieren ist, mit 12 Releases, 21 Mitwirkenden, über 800 Sternen und über 100 Gabeln?
Chris
2
Sie haben zwar einen Punkt, aber da die einzige Notwendigkeit für ein einfaches CORS ein Header ist, Access-Control-Allow-Origin: *verstehe ich nicht, warum eine ganze Sache geladen wird, werde ich in Ihrer Antwort einen anderen Weg einfügen, damit beide Methoden verfügbar sind. Referenz: [link (] enable-cors.org/server.html )
Julio Marins
2
@ JulioMarins, das wäre der Vorschlaghammer-Ansatz. Wenn Sie sich den von mir bereitgestellten Konfigurationslink ansehen, werden Sie feststellen, dass dieser django-cors-headersviel flexibler ist. Wenn Sie es vorziehen, Ihre eigene Klasse zu erstellen, seien Sie mein Gast. Aber ich würde diese Bibliothek benutzen.
Chris
4
@ Chris Ich denke, Sie sollten CORS_ORIGIN_WHITELIST hinzufügen, damit Sie den aufrufenden Host auf die Whitelist setzen.
Hakim
55
pip install django-cors-headers

und fügen Sie es dann Ihren installierten Apps hinzu:

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

Sie müssen auch eine Middleware-Klasse hinzufügen, um die Antworten abzuhören:

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

Weitere Details: https://github.com/ottoyiu/django-cors-headers/#configuration

Lesen Sie die offizielle Dokumentation kann fast alle Probleme lösen

likaiguo.happy
quelle
4
Das Hinzufügen der vier Zeilen, die Sie zu @ Chris 'Antwort hinzugefügt haben, war notwendig, damit dies für mich funktioniert.
Matt D
5
Warum ist CORS_ORIGIN_ALLOW_ALL = True, ist aber CORS_ORIGIN_WHITELISTnoch eingestellt? Die Dokumente scheinen den Eindruck zu erwecken, dass dies nicht erforderlich ist und die Antwort hier verwirrend zu sein scheint.
Phoenix
CORS_ORIGIN_ALLOW_ALL Wenn True, wird die Whitelist nicht verwendet und alle Ursprünge werden akzeptiert.
BjörnW
2
Denken Sie auch daran 'corsheaders.middleware.CorsMiddleware',, dass Sie ganz oben auf der Liste stehen müssen, da sonst die Verbindung möglicherweise abgelehnt wird, bevor Sie sie erreichen.
Sebastián Vansteenkiste
14

Sie können eine benutzerdefinierte Middleware verwenden, obwohl Sie wissen, dass die beste Option die Verwendung des getesteten Ansatzes des Pakets ist django-cors-headers. Hier ist die Lösung:

Erstellen Sie die folgende Struktur und Dateien:

- - 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

zur settings.pymarkierten Linie hinzufügen :

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
quelle
Danke Julio! Ihr Middleware-Code sollte mit dem @masnun-Codebeispiel aktualisiert werden. Außerdem funktioniert der Import bei mir nicht. behebt das Problem: from . import corsMiddleware
Pavel Daynyak
12

Für den Fall, dass jemand auf diese Frage zurückkommt und sich entscheidet, seine eigene Middleware zu schreiben, ist dies ein Codebeispiel für die neue Middleware von 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
quelle
7

Für Django-Versionen> 1.10 kann laut Dokumentation eine benutzerdefinierte MIDDLEWARE als Funktion geschrieben werden, sagen wir in der Datei: yourproject/middleware.py(als Geschwister von 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

und schließlich fügen Sie den Python-Pfad dieser Funktion (im Stammverzeichnis Ihres Projekts) zur MIDDLEWARE-Liste in Ihrem Projekt hinzu settings.py:

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

Kinderleicht!

Dhruv Batheja
quelle
Der zuvor veröffentlichte Ansatz verwendet MIDDLEWARE_CLASSES und nicht MIDDLEWARE. Diese Technik funktioniert, so dass die Abwertung unangebracht war :) @JulioMarins
Dhruv Batheja
1
Alter, die Lösung ist die gleiche. Sie streiten sich über die Implementierung der Django-Version. Ihr Code ist auch mit falschem Einzug an open_access_middleware.
Julio Marins
4

Nun, ich kenne keine Leute, aber:

mit hier Python 3.6 und Django 2.2

Das Umbenennen von MIDDLEWARE_CLASSES in MIDDLEWARE in settings.py hat funktioniert.

jnowak
quelle
3

Nachfolgend sind die Arbeitsschritte aufgeführt, ohne dass externe Module erforderlich sind:

Schritt 1: Erstellen Sie ein Modul in Ihrer App.

Nehmen wir beispielsweise an, wir haben eine App namens user_registration_app . Erkunden Sie user_registration_app und erstellen Sie eine neue Datei.

Nennen wir dies custom_cors_middleware.py

Fügen Sie die folgende Klassendefinition ein:

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

Schritt 2: Registrieren Sie eine Middleware

Fügen Sie in der Datei settings.py Ihres Projekts diese Zeile hinzu

'user_registration_app.custom_cors_middleware.CustomCorsMiddleware'

Z.B:

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

    ]

Denken Sie daran, user_registration_app durch den Namen Ihrer App zu ersetzen, in der Sie Ihr Modul custom_cors_middleware.py erstellt haben.

Sie können jetzt überprüfen, ob allen Ansichten im Projekt die erforderlichen Antwortheader hinzugefügt werden!

user3785966
quelle
0

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

Befolgen Sie die offiziellen Anweisungen funktioniert nicht

Verwenden Sie schließlich den alten Weg, um es herauszufinden.

HINZUFÜGEN:

# 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
quelle