ฉันจะเปิดใช้งาน CORS บน Django REST Framework ได้อย่างไร


113

ฉันจะเปิดใช้งาน CORS บน Django REST Framework ได้อย่างไร การอ้างอิงไม่ได้ช่วยอะไรมากนักมันบอกว่าฉันสามารถทำได้โดยมิดเดิลแวร์ แต่ฉันจะทำเช่นนั้นได้อย่างไร

คำตอบ:


171

ลิงก์ที่คุณอ้างถึงในคำถามของคุณแนะนำให้ใช้django-cors-headersซึ่งมีเอกสารระบุว่าให้ติดตั้งไลบรารี

pip install django-cors-headers

จากนั้นเพิ่มลงในแอพที่คุณติดตั้ง:

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

คุณจะต้องเพิ่มคลาสมิดเดิลแวร์เพื่อรับฟังคำตอบ:

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

โปรดเรียกดูส่วนการกำหนดค่าของเอกสารประกอบโดยให้ความสนใจเป็นพิเศษกับการCORS_ORIGIN_ตั้งค่าต่างๆ คุณจะต้องตั้งค่าบางส่วนตามความต้องการของคุณ


2
คุณรู้วิธีอื่นในการทำเช่นนั้นโดยไม่จำเป็นต้องติดตั้งการอ้างอิงใหม่หรือไม่? ฉันกำลังพยายามสร้างชนชั้นกลางตอนนี้
Julio Marins

6
@JulioMarins ทำไมคุณถึงเขียนเวอร์ชันของคุณเองในเมื่อสิ่งนี้พร้อมใช้งานและติดตั้งได้ง่ายโดยมี 12 รุ่นผู้ร่วมให้ข้อมูล 21 คนดาวกว่า 800 ดวงและส้อมมากกว่า 100 ชิ้น
คริส

2
คุณมีประเด็นแน่นอน แต่เนื่องจากความต้องการเพียงอย่างเดียวสำหรับ CORS แบบธรรมดาคือส่วนหัวAccess-Control-Allow-Origin: *ฉันไม่เห็นว่าทำไมต้องโหลดทั้งหมดฉันจะใส่วิธีอื่นในการตอบคำถามของคุณเพื่อให้ทั้งสองวิธีสามารถใช้ได้ อ้างอิง: [link (] enable-cors.org/server.html )
Julio Marins

2
@JulioMarins นั่นจะเป็นวิธีค้อนขนาดใหญ่ หากคุณดูลิงก์การกำหนดค่าที่ฉันให้ไว้คุณจะเห็นว่าdjango-cors-headersมีความยืดหยุ่นมากกว่านั้นมาก หากคุณต้องการสร้างชั้นเรียนของคุณเองเป็นแขกของฉัน แต่ฉันจะใช้ห้องสมุดนั้น
คริส

5
@ คริสฉันคิดว่าคุณควรเพิ่มCORS_ORIGIN_WHITELISTเพื่อที่คุณจะได้อนุญาตโฮสต์การโทร
Hakim

72
pip install django-cors-headers

จากนั้นเพิ่มลงในแอพที่คุณติดตั้ง:

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

คุณจะต้องเพิ่มคลาสมิดเดิลแวร์เพื่อรับฟังคำตอบ:

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

รายละเอียดเพิ่มเติม: https://github.com/ottoyiu/django-cors-headers/#configuration

อ่านเอกสารอย่างเป็นทางการสามารถแก้ไขปัญหาได้เกือบทั้งหมด


4
การเพิ่มสี่บรรทัดที่คุณเพิ่มในคำตอบของ @ คริสเป็นสิ่งจำเป็นเพื่อให้สิ่งนี้ได้ผลสำหรับฉัน
Matt D

5
ทำไมถึงเป็นCORS_ORIGIN_ALLOW_ALL = Trueแต่CORS_ORIGIN_WHITELISTยังคงตั้งค่าอยู่? เอกสารดูเหมือนจะไม่จำเป็นต้องใช้และดูเหมือนจะสับสนสำหรับคำตอบที่นี่
ต้นอินทผลัม

CORS_ORIGIN_ALLOW_ALL หากเป็นจริงรายการที่อนุญาตพิเศษจะไม่ถูกใช้และต้นกำเนิดทั้งหมดจะได้รับการยอมรับ
BjornW

3
นอกจากนี้โปรดทราบว่า'corsheaders.middleware.CorsMiddleware',ต้องอยู่ด้านบนสุดของรายการมิฉะนั้นการเชื่อมต่ออาจถูกปฏิเสธก่อนที่จะไปถึง
Sebastián Vansteenkiste

17

django-cors-headersคุณสามารถทำได้โดยใช้ตัวกลางที่กำหนดเองแม้รู้ว่าเป็นตัวเลือกที่ดีที่สุดคือการใช้วิธีการทดสอบของแพคเกจ จากที่กล่าวมานี่คือวิธีแก้ปัญหา:

สร้างโครงสร้างและไฟล์ต่อไปนี้:

- 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

เพิ่มsettings.pyในบรรทัดที่ทำเครื่องหมาย:

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! รหัสมิดเดิลแวร์ของคุณควรได้รับการอัปเดตด้วยตัวอย่างโค้ด @masnun นอกจากนี้การนำเข้าไม่ได้ผลสำหรับฉันการนำเข้าจาก แก้ไขปัญหา: from . import corsMiddleware
Pavel Daynyak

14

ในกรณีที่ใครก็ตามกลับมาที่คำถามนี้และตัดสินใจที่จะเขียนมิดเดิลแวร์ของตัวเองนี่คือตัวอย่างโค้ดสำหรับมิดเดิลแวร์สไตล์ใหม่ของ 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

8

สำหรับ Django เวอร์ชัน> 1.10 ตามเอกสารประกอบ MIDDLEWARE ที่กำหนดเองสามารถเขียนเป็นฟังก์ชันได้สมมติว่าในไฟล์: yourproject/middleware.py(ในฐานะพี่น้องของ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

และสุดท้ายเพิ่มเส้นทาง python ของฟังก์ชันนี้ (เขียนรูทของโปรเจ็กต์ของคุณ) ไปยังรายการ MIDDLEWARE ในโปรเจ็กต์ของคุณsettings.py:

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

peasy ง่าย!


แนวทางที่โพสต์ก่อนใช้ MIDDLEWARE_CLASSES ไม่ใช่ MIDDLEWARE เทคนิคนี้ใช้ได้ผลจึงไม่ได้รับการโหวตลงคะแนน :) @JulioMarins
Dhruv Batheja

1
เพื่อนวิธีแก้ปัญหาก็เหมือนกัน คุณกำลังโต้เถียงเกี่ยวกับการนำไปใช้กับเวอร์ชัน Django รหัสของคุณมีการเยื้องผิดopen_access_middlewareด้วย
Julio Marins

5

ด้านล่างนี้เป็นขั้นตอนการทำงานโดยไม่ต้องใช้โมดูลภายนอกใด ๆ :

ขั้นตอนที่ 1:สร้างโมดูลในแอปของคุณ

เช่นสมมติว่าเรามีแอปชื่อuser_registration_app user_registration_appสำรวจ user_registration_app และสร้างไฟล์ใหม่

ให้เรียกสิ่งนี้ว่า custom_cors_middleware.py

วางคำจำกัดความของคลาสด้านล่าง:

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

ขั้นตอนที่ 2:ลงทะเบียนมิดเดิลแวร์

ในไฟล์ settings.py โปรเจ็กต์ของคุณให้เพิ่มบรรทัดนี้

'user_registration_app.custom_cors_middleware.CustomCorsMiddleware'

เช่น:

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

    ]

อย่าลืมแทนที่user_registration_appด้วยชื่อแอปของคุณที่คุณสร้างโมดูล custom_cors_middleware.py

ตอนนี้คุณสามารถตรวจสอบได้ว่าจะเพิ่มส่วนหัวการตอบกลับที่จำเป็นในมุมมองทั้งหมดในโครงการ!


ขอขอบคุณ! ฉันไม่มีส่วนหัว Access-Control-Allow-Headers
แดน

4

ฉันไม่รู้จักผู้ชาย แต่:

โดยใช้ python 3.6 และ django 2.2 ที่นี่

เปลี่ยนชื่อ MIDDLEWARE_CLASSES เป็น MIDDLEWARE ใน settings.py ใช้งานได้


0

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

ทำตามคำสั่งอย่างเป็นทางการไม่ได้ผล

สุดท้ายใช้วิธีคิดแบบเก่า

เพิ่ม:

# 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',
    ),
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.