CORS, HttpOnly, CSRFCookie; Django; ReactJS

У меня есть вопрос. Я разрабатываю webApp. Мой backend находится на xxxx.xxxx.xxxx.xxxx.xxxx:8000 и мой frontend находится на xxxx.xxxx.xxxx.xxxx:3000. Я использую Django и ReactJS. Я настроил политику CORS на бэкенде, чтобы разрешить только фронтенду делать запросы.

Итак. Всякий раз, когда мне нужно получить CSRF cookies из моего бэкенда, они приходят в ответе под Set-Cookie с HttpOnly флагом.

Мой вопрос заключается в том, что если мы не должны извлекать куки HttpOnly с помощью JS, почему я все еще могу делать это в моем приложении ReactJS. Однако, когда я убираю этот флаг, я больше не могу устанавливать или извлекать эти куки из заголовка. Что не так? Или что правильно?

Помогите мне понять это, пожалуйста.

моя настройка CORS в django:

# CSRF Cookie Settings
CSRF_COOKIE_AGE: Optional[int] = None

CSRF_TRUSTED_ORIGINS = [
    'http://localhost:3000',
    'http://xxxx.xxxx.xxxx.xxxx:3000'
]

CSRF_COOKIE_HTTPONLY = True

# CORS(cross origin resource sharing) settings
CORS_ORIGIN_ALLOW_ALL = False

CORS_ALLOW_CREDENTIALS = True

CORS_ALLOWED_ORIGINS = [
    'http://localhost:3000',
    'http://xxxx.xxxx.xxxx.xxxx:3000',
]

CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'PATCH',
'POST',
'PUT',
]


мой запрос reactjs:

fetch("http://xxxx.xxxx.xxxx.xxxx:8000/get_csrf",{
      method: 'GET',
      mode: 'cors',
      credentials:'same-origin',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      }
    })
      .then(response => {
        console.log(...response.headers)
        response.json()
      })
      .then(
        (result) => {
          console.log(this.getCookie('csrftoken'))
        },

        (error) => {

        }
      )

TL;DR

Вы не можете.

Подробнее

Мой backend находится на xxxx.xxxx.xxxx.xxxx.xxxx:8000, а мой frontend находится на xxxx.xxxx.xxxx.xxxx:3000.

Обратите внимание, что ваш запрос является кросс-оригинальным.

Помните, что Fetch Standard (фактическая спецификация CORS) относит Set-Cookie к категории запрещенных имен заголовков ответа. Поэтому, независимо от конфигурации CORS сервера, браузеры не позволяют клиенту читать такие заголовки из ответа на кросс-оригинальный запрос.

Веб-документы MDN о заголовке ответа Set-Cookie, которые могут быть неавторитетным источником истины, но их легче читать, чем стандарт Fetch, содержат следующее уточняющее предупреждение:

Браузеры блокируют доступ JavaScript-кода фронтенда к заголовку Set-Cookie, как того требует спецификация Fetch, которая определяет Set-Cookie как запрещенное имя заголовка ответа, которое должно быть отфильтровано из любого ответа, открываемого для кода фронтенда.

Так что я собрал немного больше информации и выяснил, как правильно его настроить.

  1. Да, мы не можем получить доступ к HttpOnly cookies.
  2. Необходимо иметь credentials:'include' в запросе fetch JS.
  3. Необходимо иметь mode: 'cors' в запросе JS.
  4. В Django settings.py:
CORS_ORIGIN_ALLOW_ALL = False

CORS_ALLOW_CREDENTIALS = True

CORS_ALLOWED_ORIGINS = [
    'http://localhost:3000',
    'http://xxx.xxx.xxx.xxx:3000',
]

CORS_ALLOW_METHODS = [
    'DELETE',
    'GET',
    'PATCH',
    'POST',
    'PUT',
]

CORS_EXPOSE_HEADERS = [
    'Date'
]

Вернуться на верх