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
как запрещенное имя заголовка ответа, которое должно быть отфильтровано из любого ответа, открываемого для кода фронтенда.
Так что я собрал немного больше информации и выяснил, как правильно его настроить.
- Да, мы не можем получить доступ к
HttpOnly
cookies. - Необходимо иметь
credentials:'include'
в запросе fetch JS. - Необходимо иметь
mode: 'cors'
в запросе JS. - В 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'
]