Сьогодні ми освоїмо налаштування 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": "Привіт, світ!"})
Проте, такий підхід рідко використовується, оскільки у більшості випадків усі налаштування якості обробляються глобально.
Практичне завдання
Завдання: підключаємо зовнішній фронтенд
Кроки:
- Створіть простий REST API у Django — наприклад, список завдань (ToDo).
- Налаштуйте CORS для дозволу запитів із домену
http://localhost:3000. - Підключіть ваш API до фронтенд-додатку (наприклад, React).
- Спробуйте відправити запити
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 безпечним і доступним у рамках сучасних стандартів веб-розробки.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ