JavaRush /Курсы /Модуль 3: Django /Настройка CORS в Django для работы с внешними фронтенд-пр...

Настройка CORS в Django для работы с внешними фронтенд-приложениями

Модуль 3: Django
21 уровень , 6 лекция
Открыта

Сегодня мы освоим настройку CORS (Cross-Origin Resource Sharing) в Django.

Вообразите ситуацию: вы создали блестящее API. Всё работает идеально, пока вы не решите подключить ваше любимое фронтенд-приложение, запущенное на другом домене или порту.
Пример: ваш сервер работает на http://127.0.0.1:8000, а фронтенд — на http://localhost:3000.
Тут в игру вступает CORS — Cross-Origin Resource Sharing.

Браузеры, из соображений безопасности, блокируют запросы к API, которые отправляются с одного домена (например, http://localhost:3000) к серверу на другом домене (например, http://127.0.0.1:8000).
Это называется Same-Origin Policy — механизм, предотвращающий отправку запросов от вашего имени к другим ресурсам без разрешения.

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

Установка и настройка django-cors-headers

В Django есть несколько способов настроить CORS, но самый популярный и удобный — это библиотека django-cors-headers. Давайте установим и настроим её.

pip install django-cors-headers

Шаг 1: подключение приложения

После установки необходимо зарегистрировать приложение в INSTALLED_APPS. Откройте файл settings.py и добавьте:

INSTALLED_APPS = [
    ...
    'corsheaders',
    ...
]

Чтобы библиотека могла обрабатывать запросы до того, как они попадут в Django Middleware, добавьте corsheaders.middleware.CorsMiddleware в список MIDDLEWARE прямо после SecurityMiddleware:

MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]

Шаг 2: базовая настройка CORS

Теперь, когда приложение добавлено, нужно указать, каким доменам разрешено обращаться к вашему API. Для этого добавьте в settings.py параметр CORS_ALLOWED_ORIGINS:

CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",  # Разрешаем доступ фронтенду с порта 3000
    "http://127.0.0.1:3000", # Еще один вариант локального хоста
]

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

Настройка wildcard-домена для всех источников (НЕ РЕКОМЕНДУЕТСЯ)

Если вы хотите разрешить доступ всем доменам (например, для разработки), можно использовать настройку CORS_ALLOW_ALL_ORIGINS. Будьте осторожны с этим параметром, так как он может поставить вашу систему под угрозу в продакшен-среде.

CORS_ALLOW_ALL_ORIGINS = True

Помните: никогда не используйте CORS_ALLOW_ALL_ORIGINS = True в продакшене. Вы не хотите, чтобы кто угодно, где угодно мог делать запросы к вашему API.

Настройка допустимых методов и заголовков

Библиотека django-cors-headers позволяет дополнительно настроить методы HTTP и заголовки, которые сервер разрешает обрабатывать. Например:

По умолчанию разрешены только стандартные HTTP-методы: GET, POST, PUT, PATCH, DELETE, OPTIONS. Если вам нужно разрешить другие методы, используйте следующую настройку:

CORS_ALLOW_METHODS = [
    "GET",
    "POST",
    "PUT",
    "DELETE",
    "OPTIONS",
    "PATCH",
]

Если ваш фронтенд отправляет дополнительные заголовки (например, Authorization для аутентификации), их нужно явно указать:

CORS_ALLOW_HEADERS = [
    "content-type",
    "authorization",
    "x-csrf-token",
]

Политики CORS для конкретных эндпоинтов

Иногда вам может понадобиться разрешить CORS только для определённых эндпоинтов. Например, открытые ресурсы, такие как "список товаров", могут быть доступны всем, а приватные ресурсы — только аутентифицированным пользователям.

Для таких случаев можно использовать декоратор @cors_allow_all.

Пример настройки:

from corsheaders.decorators import cors_allow_all

@cors_allow_all
def my_open_endpoint(request):
    return JsonResponse({"message": "Hello, world!"})

Однако, такой подход редко используется, так как в большинстве случаев все настройки качества обрабатываются глобально.

Практическое задание

Задание: подключаем внешний фронтенд

Шаги:

  1. Создайте простое REST API в Django — например, список задач (ToDo).
  2. Настройте CORS для разрешения запросов с домена http://localhost:3000.
  3. Подключите ваше API к фронтенд-приложению (например, React).
  4. Попробуйте отправить запросы GET и POST с фронтенда. Проверьте, что ошибки CORS больше не возникают.

Решение

# settings.py
INSTALLED_APPS = [
    ...
    'corsheaders',
    ...
]

MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]

CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
]
# views.py
from django.http import JsonResponse
from rest_framework.decorators import api_view

@api_view(["GET"])
def todo_list(request):
    todos = [
        {"id": 1, "task": "Изучить Django", "completed": False},
        {"id": 2, "task": "Написать REST API", "completed": True},
    ]
    return JsonResponse(todos, safe=False)

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

import axios from 'axios';

axios.get("http://127.0.0.1:8000/api/todos/")
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error("Ошибка:", error);
  });

Частые проблемы и их решения

Иногда вам могут встретиться ошибки, даже если вы всё настроили правильно.

Проблема: ошибка No Access-Control-Allow-Origin header is present on the requested resource

Эта проблема обычно возникает, если вы забыли добавить ваш фронтенд-домен в CORS_ALLOWED_ORIGINS. Убедитесь, что он указан в settings.py.

Проблема: ошибка CORS при использовании авторизации

Если вы используете токены для доступа, убедитесь, что заголовок Authorization добавлен в список CORS_ALLOW_HEADERS.

CORS_ALLOW_HEADERS = [
    "content-type",
    "authorization",
]

Настройка CORS — это важный шаг в интеграции вашего Django-приложения с внешними фронтенд-приложениями. Она позволяет сделать API безопасным и доступным в рамках современных стандартов веб-разработки.

1
Задача
Модуль 3: Django, 21 уровень, 6 лекция
Недоступна
Разрешение доступа для конкретных доменов
Разрешение доступа для конкретных доменов
1
Задача
Модуль 3: Django, 21 уровень, 6 лекция
Недоступна
Настройка HTTP-методов и заголовков для CORS
Настройка HTTP-методов и заголовков для CORS
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ