Bagaimana saya dapat mengaktifkan CORS pada Django REST Framework

107

Bagaimana saya dapat mengaktifkan CORS pada Django REST Framework saya? yang referensi tidak banyak membantu, ia mengatakan bahwa saya bisa melakukan dengan middleware, tapi bagaimana saya bisa melakukan itu?

Julio Marins
sumber

Jawaban:

162

Tautan yang Anda rujuk dalam pertanyaan Anda merekomendasikan penggunaan django-cors-headers, yang dokumentasinya mengatakan untuk menginstal pustaka

pip install django-cors-headers

dan kemudian tambahkan ke aplikasi yang Anda instal:

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

Anda juga perlu menambahkan kelas middleware untuk mendengarkan tanggapan:

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

Silakan telusuri bagian konfigurasi dari dokumentasinya, dengan memberi perhatian khusus pada berbagai CORS_ORIGIN_pengaturan. Anda harus mengatur beberapa di antaranya berdasarkan kebutuhan Anda.

Chris
sumber
2
apakah Anda tahu cara lain untuk melakukannya, tanpa perlu menginstal dependensi baru? Saya mencoba membuat kelas middleware sekarang
Julio Marins
5
@JulioMarins, mengapa Anda menulis versi Anda sendiri ketika versi ini sudah tersedia dan mudah diinstal, dengan 12 rilis, 21 kontributor, lebih dari 800 bintang dan lebih dari 100 fork?
Chris
2
Anda benar, tetapi karena satu-satunya kebutuhan untuk CORS sederhana adalah tajuk. Access-Control-Allow-Origin: *Saya tidak mengerti mengapa memuat semuanya, saya akan memberikan cara lain untuk melakukan ini dalam jawaban Anda sehingga kedua metode dapat tersedia. referensi: [link (] enable-cors.org/server.html )
Julio Marins
2
@JulioMarins, itu akan menjadi pendekatan palu godam. Jika Anda melihat tautan konfigurasi yang saya sediakan, Anda akan melihat bahwa django-cors-headersjauh lebih fleksibel dari itu. Jika Anda lebih suka membuat kelas Anda sendiri, jadilah tamu saya. Tapi saya akan menggunakan perpustakaan itu.
Chris
4
@ Chris Saya rasa Anda harus menambahkan CORS_ORIGIN_WHITELIST sehingga Anda memasukkan host pemanggil ke daftar putih.
Hakim
68
pip install django-cors-headers

dan kemudian tambahkan ke aplikasi yang Anda instal:

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

Anda juga perlu menambahkan kelas middleware untuk mendengarkan tanggapan:

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

detail lebih lanjut: https://github.com/ottoyiu/django-cors-headers/#configuration

membaca dokumentasi resmi dapat menyelesaikan hampir semua masalah

likaiguo.happy
sumber
4
Menambahkan empat baris yang Anda tambahkan ke jawaban @ Chris diperlukan agar ini berhasil bagi saya.
Matt D
5
Kenapa CORS_ORIGIN_ALLOW_ALL = True, tapi CORS_ORIGIN_WHITELISTmasih disetel? Dokumen tampaknya membuatnya tampak seperti ini tidak diperlukan dan tampaknya membingungkan untuk jawabannya di sini.
phoenix
CORS_ORIGIN_ALLOW_ALL Jika True, daftar putih tidak akan digunakan dan semua yang asli akan diterima.
BjornW
2
Juga perlu diingat 'corsheaders.middleware.CorsMiddleware',harus agak di bagian atas daftar, jika tidak koneksi mungkin ditolak sebelum mendapatkannya.
Sebastián Vansteenkiste
16

Anda dapat melakukannya dengan menggunakan middleware kustom, meskipun mengetahui bahwa opsi terbaik adalah menggunakan pendekatan paket yang telah diuji django-cors-headers. Karena itu, inilah solusinya:

buat struktur dan file berikut:

- 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

tambahkan ke settings.pygaris yang ditandai:

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
sumber
Terima kasih Julio! Kode middleware Anda harus diperbarui dengan contoh kode @masnun. Selain itu, impor tidak berfungsi untuk saya, mengimpor dari. memperbaiki masalah: from . import corsMiddleware
Pavel Daynyak
14

Jika ada yang kembali ke pertanyaan ini dan memutuskan untuk menulis middleware mereka sendiri, ini adalah contoh kode untuk middleware gaya baru 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
sumber
7

Untuk versi Django> 1.10, menurut dokumentasinya , sebuah MIDDLEWARE kustom dapat ditulis sebagai fungsi, katakanlah dalam file: yourproject/middleware.py(sebagai saudara dari 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

dan terakhir, tambahkan jalur python dari fungsi ini (wrt root proyek Anda) ke daftar MIDDLEWARE di proyek Anda settings.py:

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

Sangat mudah!

Dhruv Batheja
sumber
Pendekatan yang diposting sebelumnya menggunakan MIDDLEWARE_CLASSES dan bukan MIDDLEWARE. Teknik ini bekerja sehingga downvote tidak pantas :) @JulioMarins
Dhruv Batheja
1
Bung, solusinya sama. Anda berdebat tentang implementasi pada versi Django. Kode Anda juga dengan indentasi yang salah open_access_middleware.
Julio Marins
4

Yah, saya tidak tahu teman-teman tapi:

menggunakan di sini python 3.6 dan django 2.2

Mengganti nama MIDDLEWARE_CLASSES menjadi MIDDLEWARE di settings.py berhasil.

jnowak.dll
sumber
4

Di bawah ini adalah langkah-langkah kerja tanpa memerlukan modul eksternal:

Langkah 1: Buat modul di aplikasi Anda.

Misalnya, anggap saja kita memiliki aplikasi bernama user_registration_app . Jelajahi user_registration_app dan buat file baru.

Mari kita sebut ini sebagai custom_cors_middleware.py

Tempel definisi Kelas di bawah ini:

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

Langkah 2: Daftarkan middleware

Dalam file settings.py proyek Anda, tambahkan baris ini

'user_registration_app.custom_cors_middleware.CustomCorsMiddleware'

Misalnya:

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

    ]

Ingatlah untuk mengganti user_registration_app dengan nama aplikasi tempat Anda membuat modul custom_cors_middleware.py.

Anda sekarang dapat memverifikasi bahwa itu akan menambahkan header respons yang diperlukan ke semua tampilan dalam proyek!

pengguna3785966
sumber
Terima kasih! Saya kehilangan header Access-Control-Allow-Headers.
Dan
0

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

Ikuti instruksi resmi tidak berhasil

Akhirnya gunakan cara lama untuk mengetahuinya.

MENAMBAHKAN:

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