У меня проблема с CORS с моим Django Rest Framework и приложением React на одном сервере.Я использую Vagrant с Ubuntu 18 и установленным NGINX (я предполагаю, что эта проблема преобразуется в DigitalOcean). Я заранее извиняюсь, если предоставляю слишком много информации.DRF использует Supervisor, а Gunicorn находится на порту 8000. Я создал свое приложение React с помощью create-реагировать-приложение.Затем я использовал npm run build
для создания статических файлов.
Настройка NGINX:
React Conf
server {
listen 8080;
server_name sandbox.dev;
root /var/sites/sandbox/frontend/build;
index index.html;
client_max_body_size 4G;
location / {
try_files $uri $uri/ /index.html;
}
Django Conf
upstream sandbox_server {
server unix:/var/tmp/gunicorn_sanbox.sock fail_timeout=0;
}
server {
listen 8000;
server_name api.sandbox.dev;
...
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://sandbox_server;
break;
}
Настройка Django:
INSTALLED_APPS = [
...
'rest_framework',
'corsheaders',
'myapp',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
...
]
Я попробовал следующее без удачи
CORS_ORIGIN_ALLOW_ALL = True
и
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = ('192.168.19.76:8080','localhost:8080',)
React App.js
...
fetch("http://localhost:8000/api/v1/token-auth/", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({"email":"test@user.com", "password":"testuser"}),
})
Таким образом, утверждение очевидного CORS является правильным, поскольку источником является localhost: 8080, который является другим портом, поэтому он видит его как перекрестный источник.Я пробовал разные настройки разрешения cors origin, но это все равно одна и та же проблема каждый раз.Очевидно, я делаю что-то не так, но не вижу этого.
Мои мысли:
Вариант 1
передача прокси с помощью файла conf django nginx и отказ от файла Confact nginx, но я не знаю, как это повлияетможет вызвать в производстве или если это хорошая идея.Есть ли лучший способ?
location /api {
proxy_set_header X-Forwarded_for $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://sandbox_server;
Так что завершите мои мысли и мой вопрос.После попытки различных вариантов Django для CORS я все еще получаю ошибку CORS.Почему, и это мои файлы NGINX conf вызывают это или что-то еще?Ожидаю ли я увидеть это в DigitalOcean?
ОБНОВЛЕНИЕ 1
Я забыл добавить ошибку.Вот ошибка CORS
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/api/v1/token-auth/. (Reason: CORS request did not succeed).
Для тех, кто хочет знать вывод на вкладке сети
Host localhost:8000
Origin http://192.168.19.76:8080
Pragma no-cache
Referer http://192.168.19.76:8080/
ОБНОВЛЕНИЕ 2 Я тестировал с помощью curl, и всевернулся, как и ожидалось, поэтому я знаю, что DRF работает без ошибок.
curl --data "email=test@user.com&password=testuser" http://localhost:8000/api/v1/token-auth/
ОБНОВЛЕНИЕ ОБНОВЛЕНИЯ
Спасибо paulsm4 за помощь и просто потрясающую информацию.
Итак, я отказался от django-cors-headers и свернул свой собственный.Чтобы ответить на вопрос paulsm4, у меня нет add_header 'Access-Control-Allow-Origin' '*';
в файле NGINX, хотя я и думал о том, чтобы позволить NGINX обрабатывать CORS против Django, но никогда не заходил так далеко.@ paulsm4, это тот proxy_pass, о котором я говорил.Ключом было добавление этого блока кода в NGINX для части реакции в сочетании с моим промежуточным программным обеспечением.
location /api {
proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://sandbox_server;
Вышеприведенный код сам по себе работал, но он не позволял мне вносить в белый список любые входящие URL-адреса.Создание собственного промежуточного программного обеспечения позволило мне занести белый список.Я понятия не имею, почему django-cors-headers или даже django-cors-middleware не работают для меня.Странно было то, что с этими двумя пакетами fetch никогда не заходил достаточно далеко, чтобы получить заголовки ответов и ошибки любого рода, кроме ошибки CORS, о которой я спрашивал.С промежуточным программным обеспечением, которое я написал, fetch смог полностью выполнить вызов и вернуть некоторые заголовки ответа, независимо от того, был он успешным или нет.
Для дальнейшего использования я мог бы вернуться к NGINX и позволить ему обрабатывать CORS.Вот хорошая ссылка CORS на NGINX
NOTE
Чтобы уточнить;единственное установленное промежуточное программное обеспечение, помимо того, что уже включено в Django, - это промежуточное программное обеспечение Cors.Django и React находятся на одном сервере, но с разными портами.
- api.sandbox.com: 8000 - это Django Rest Framework
- app.sandbox.com: 8080 -Реактивные статические файлы
- Django 2.0.2
- Python 3.6
- django-cors-заголовки 2.4.0
- Vagrant / VirtualBox Ubuntu 18.04
- NGINX
Django settings.py
INSTALLED_APPS = [
...
# Third Party
'rest_framework',
'corsheaders',
# My Apps
'account',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
'django.middleware.csrf.CsrfViewMiddleware',
'corsheaders.middleware.CorsPostCsrfMiddleware',
...
]
CORS_ORIGIN_WHITELIST = (
'null',
'192.168.19.76:8080',
'localhost:8080',
'app.sandbox.com:8080'
)
Реагировать App.js
fetch("http://localhost:8000/api/v1/token-auth/", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email": "test@user.com",
"password": "testuser"
}),
})
Так что я нахожусь в этом конце.Либо django-cors-headers не работает, либо это может быть NGINX.