Как включить CORS в Django REST Framework

Ответы:

162

Ссылка, на которую вы ссылаетесь в своем вопросе, рекомендует использовать django-cors-headers, документация которой говорит об установке библиотеки

pip install django-cors-headers

а затем добавьте его в установленные приложения:

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

Вам также потребуется добавить класс промежуточного программного обеспечения для прослушивания ответов:

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

Просмотрите раздел конфигурации документации, обращая особое внимание на различные CORS_ORIGIN_настройки. Вам нужно будет установить некоторые из них в зависимости от ваших потребностей.

Крис
источник
2
знаете ли вы какой-либо другой способ сделать это без необходимости установки новой зависимости? Сейчас я пытаюсь создать класс промежуточного программного обеспечения
Хулио Маринс
5
@JulioMarins, зачем вам писать свою собственную версию, если она легко доступна и легко устанавливается, с 12 выпусками, 21 участником, более 800 звезд и более 100 форков?
Крис
2
Вы действительно правы, но поскольку единственная потребность в простом CORS - это заголовок, Access-Control-Allow-Origin: *я не понимаю, зачем загружать все это, я предложу другой способ сделать это в вашем ответе, чтобы оба метода были доступны. ссылка: [ссылка (] enable-cors.org/server.html )
Хулио Маринс
2
@JulioMarins, это был бы подход кувалды. Если вы посмотрите ссылку на конфигурацию, которую я предоставил, вы увидите, что django-cors-headersона намного более гибкая. Если вы предпочитаете создать свой собственный класс, будь моим гостем. Но я бы использовал эту библиотеку.
Крис
4
@Chris Я думаю, вам следует добавить CORS_ORIGIN_WHITELIST, чтобы внести вызывающий хост в белый список.
Хаким
68
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

чтение официальной документации может решить почти все проблемы

likaiguo.happy
источник
4
Добавление четырех строк, которые вы добавили в ответ @Cris, было необходимо, чтобы это сработало для меня.
Matt D
5
Почему есть CORS_ORIGIN_ALLOW_ALL = True, но CORS_ORIGIN_WHITELISTвсе равно установлено? Документы, похоже, создают впечатление, что это не требуется и, похоже, сбивает с толку ответ здесь.
феникс
CORS_ORIGIN_ALLOW_ALL Если True, белый список не будет использоваться и будут приняты все источники.
BjornW
2
Также имейте в виду, что он 'corsheaders.middleware.CorsMiddleware',должен находиться в верхней части списка, иначе соединение может быть отклонено до того, как оно будет достигнуто.
Себастьян Ванстенкисте,
16

Вы можете сделать это, используя настраиваемое промежуточное программное обеспечение, даже зная, что лучший вариант - использовать протестированный подход пакета 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
)
Хулио Маринс
источник
Спасибо, Хулио! Ваш код промежуточного программного обеспечения должен быть обновлен с помощью примера кода @masnun. Также у меня не работает импорт, импорт из. устраняет проблему: from . import corsMiddleware
Павел Дайняк
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
Маснун
источник
7

Для версий 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'
]

Очень просто!

Дхрув Батеджа
источник
Опубликованный ранее подход использует MIDDLEWARE_CLASSES, а не MIDDLEWARE. Этот метод работает, поэтому отрицательный голос не был вызван :) @JulioMarins
Dhruv Batheja
1
чувак, решение то же самое. Вы спорите о реализации в версии Django. В вашем коде также неправильный отступ open_access_middleware.
Хулио Маринс
4

Ну не знаю, ребята, но:

используя здесь python 3.6 и django 2.2

Переименование MIDDLEWARE_CLASSES в MIDDLEWARE в settings.py работало.

Jnowak
источник
4

Ниже приведены этапы работы без внешних модулей:

Шаг 1. Создайте модуль в своем приложении.

Например, предположим, что у нас есть приложение с именем 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.

Теперь вы можете убедиться, что он добавит необходимые заголовки ответов во все представления в проекте!

пользователь3785966
источник
Спасибо! Мне не хватало заголовка Access-Control-Allow-Headers.
Дэн
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',
    ),
}
СК
источник