Проблема CORS с Django и React, размещенными на одном сервере - PullRequest
0 голосов
/ 25 января 2019

У меня проблема с 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 находятся на одном сервере, но с разными портами.

  1. api.sandbox.com: 8000 - это Django Rest Framework
  2. app.sandbox.com: 8080 -Реактивные статические файлы
  3. Django 2.0.2
  4. Python 3.6
  5. django-cors-заголовки 2.4.0
  6. Vagrant / VirtualBox Ubuntu 18.04
  7. 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.

1 Ответ

0 голосов
/ 26 января 2019

Мы обмениваемся комментариями; вот мое текущее понимание:

ПРОБЛЕМА : у вас есть внутренний интерфейс Django (на порту 8080) и интерфейс React (на порту 8000). Оба в настоящее время работают на локальном хосте, но в конечном итоге будут находиться в DigitalOcean. Клиент React получает 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).

Вам необходимо настроить CORS.

Заголовки запросов в перехваченном HTTP-трафике ясно показывают, что этого еще не произошло.

Некоторые соответствующие ссылки включают в себя:

ПРЕДЛАГАЕМЫЙ СЛЕДУЮЩИЙ ШАГ:

Если вы этого еще не сделали, пожалуйста, установите и настройте django-cors-headers

...