Jak mogę włączyć CORS w Django REST Framework

Odpowiedzi:

164

Odnośnik, o którym wspomniałeś w swoim pytaniu, zaleca użycie django-cors-headers, którego dokumentacja mówi o zainstalowaniu biblioteki

pip install django-cors-headers

a następnie dodaj go do zainstalowanych aplikacji:

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

Będziesz także musiał dodać klasę oprogramowania pośredniego, aby nasłuchiwać odpowiedzi:

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

Przejrzyj sekcję dotyczącą konfiguracji w jego dokumentacji, zwracając szczególną uwagę na różne CORS_ORIGIN_ustawienia. Musisz ustawić niektóre z nich w zależności od swoich potrzeb.

Chris
źródło
2
czy znasz inny sposób, aby to zrobić, bez konieczności instalowania nowej zależności? Próbuję teraz stworzyć klasę oprogramowania pośredniego
Julio Marins
5
@JulioMarins, dlaczego miałbyś pisać własną wersję, skoro jest ona łatwo dostępna i łatwa do zainstalowania, z 12 wydaniami, 21 współtwórcami, ponad 800 gwiazdkami i ponad 100 widelcami?
Chris
2
Rzeczywiście masz rację, ale ponieważ prosty CORS potrzebny jest tylko w nagłówku Access-Control-Allow-Origin: *, nie widzę powodu, aby ładować całość, przedstawię inny sposób zrobienia tego w twojej odpowiedzi, aby obie metody były dostępne. źródło : [link (] enable-cors.org/server.html )
Julio Marins
2
@JulioMarins, to byłoby podejście młotem kowalskim. Jeśli spojrzysz na link konfiguracyjny, który podałem, zobaczysz, że django-cors-headersjest on znacznie bardziej elastyczny. Jeśli wolisz stworzyć własną klasę, bądź moim gościem. Ale używałbym tej biblioteki.
Chris
4
@Chris Myślę, że powinieneś dodać CORS_ORIGIN_WHITELIST, aby umieścić na białej liście hosta wywołującego.
Hakim
69
pip install django-cors-headers

a następnie dodaj go do zainstalowanych aplikacji:

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

Będziesz także musiał dodać klasę oprogramowania pośredniego, aby nasłuchiwać odpowiedzi:

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

więcej szczegółów: https://github.com/ottoyiu/django-cors-headers/#configuration

Przeczytaj oficjalną dokumentację może rozwiązać prawie każdy problem

likaiguo.happy
źródło
4
Dodanie czterech linii, które dodałeś do odpowiedzi @ Chris było konieczne, aby to zadziałało.
Matt D
5
Dlaczego tak jest CORS_ORIGIN_ALLOW_ALL = True, ale CORS_ORIGIN_WHITELISTnadal jest ustawione? Dokumenty wydają się sugerować, że nie jest to wymagane i wydaje się być mylące, jeśli chodzi o odpowiedź tutaj.
feniks
CORS_ORIGIN_ALLOW_ALL Jeśli prawda, biała lista nie będzie używana, a wszystkie źródła będą akceptowane.
BjornW
3
Należy również pamiętać, 'corsheaders.middleware.CorsMiddleware',że należy raczej znajdować się na górze listy, w przeciwnym razie połączenie może zostać odrzucone przed uzyskaniem do niego dostępu.
Sebastián Vansteenkiste
16

Możesz to zrobić, korzystając z niestandardowego oprogramowania pośredniego, nawet wiedząc, że najlepszą opcją jest użycie przetestowanego podejścia pakietu django-cors-headers. Mając to na uwadze, oto rozwiązanie:

utwórz następującą strukturę i pliki:

- 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

dodaj do settings.pyzaznaczonej linii:

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
źródło
Dzięki Julio! Twój kod oprogramowania pośredniego powinien zostać zaktualizowany o przykładowy kod @masnun. Również import nie działa dla mnie, importowanie z. rozwiązuje problem: from . import corsMiddleware
Pavel Daynyak
14

Na wypadek, gdyby ktoś wracał do tego pytania i decydował się napisać własne oprogramowanie pośredniczące, jest to przykładowy kod dla oprogramowania pośredniczącego nowego stylu 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
źródło
7

Dla wersji Django> 1.10, zgodnie z dokumentacją , niestandardowe OPROGRAMOWANIE ŚRODKOWE może zostać zapisane jako funkcja, powiedzmy w pliku: yourproject/middleware.py(jako rodzeństwo 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

i na koniec dodaj ścieżkę Pythona do tej funkcji (wrt root twojego projektu) do listy MIDDLEWARE w twoim projekcie settings.py:

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

Bułka z masłem!

Dhruv Batheja
źródło
Podejście opublikowane wcześniej używa MIDDLEWARE_CLASSES, a nie MIDDLEWARE. Ta technika działa, więc głos przeciw nie został uznany :) @JulioMarins
Dhruv Batheja
1
koleś, rozwiązanie jest takie samo. Spierasz się o implementację w wersji Django. Twój kod ma również niewłaściwe wcięcie open_access_middleware.
Julio Marins
4

Cóż, nie znam facetów, ale:

używając tutaj Pythona 3.6 i django 2.2

Zmiana nazwy MIDDLEWARE_CLASSES na MIDDLEWARE w settings.py zadziałała.

jnowak
źródło
4

Poniżej znajdują się kroki robocze bez konieczności stosowania zewnętrznych modułów:

Krok 1: Utwórz moduł w swojej aplikacji.

Załóżmy na przykład, że mamy aplikację o nazwie user_registration_app . Przeglądaj user_registration_app i utwórz nowy plik.

Nazwijmy to custom_cors_middleware.py

Wklej poniższą definicję klasy:

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

Krok 2: Zarejestruj oprogramowanie pośredniczące

W pliku settings.py projektów dodaj tę linię

„user_registration_app.custom_cors_middleware.CustomCorsMiddleware”

Na przykład:

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

    ]

Pamiętaj, aby zastąpić user_registration_app nazwą swojej aplikacji, w której utworzyłeś moduł custom_cors_middleware.py.

Możesz teraz sprawdzić, czy doda wymagane nagłówki odpowiedzi do wszystkich widoków w projekcie!

user3785966
źródło
Dziękuję Ci! Brakowało mi nagłówka Access-Control-Allow-Headers.
Dan
0

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

Postępuj zgodnie z oficjalną instrukcją, która nie działa

Wreszcie użyj starego sposobu, aby to rozgryźć.

DODAJ:

# 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
źródło