Токен CSRF в Angular+Django не сохраняется в cookie
У меня есть веб-приложение с Angular frontend и Django backend. Все работает хорошо локально, поэтому я развернул бэкенд на PythonAnywhere. Я использую CSRF-токены, поэтому, как только пользователь открывает страницу, пустой запрос отправляется на бэкэнд, который отвечает токеном, автоматически сохраняемым в куки. Однако это не работает, когда я разворачиваю бэкэнд. Я вижу, что токен находится в ответе, но он не появляется в хранилище браузера, и его нельзя использовать для следующих запросов.
Я не уверен, как это вообще можно отладить. Что может быть причиной этого?
Вот соответствующая часть моего setttings.py
:
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
]
CORS_ALLOWED_ORIGINS = (
'http://localhost:4200',
)
CSRF_TRUSTED_ORIGINS = (
'http://localhost:4200',
)
CORS_ALLOW_CREDENTIALS = True
CSRF_COOKIE_SAMESITE = 'None'
CSRF_COOKIE_SECURE = True
Я получаю ту же проблему при развертывании фронтенда (затем я также добавляю его в качестве доверенного источника, но я пропустил это в этом извлечении).
Как я уже сказал, я вижу токен в ответе в сетевом представлении браузера, но он никогда не попадает в хранилище браузера. И все работает нормально при локальном запуске того же бэкенда.
Настройки cookie должны быть следующими:
SameSite=None # Mandatory
Secure =True # Mandatory
HttpOnly=True # Optional but recommended
Похоже, что вы уже правильно настроили эту часть. Ваша конфигурация CORS также выглядит правильной.
Не имея информации о вашем фронтенде, я могу лишь предположить, что последним шагом теперь будет указание бэкенду включать сторонние cookies (а в глазах вашего браузера ваш бэкенд является сторонним).
То, как вы это сделаете, зависит от того, как вы посылаете вызовы. Для fetch это будет выглядеть так:
fetch('https://backend.com/', {
method: 'GET',
credentials: 'include',
})
Заметным недостатком этой установки является то, что ее трудно разрабатывать/тестировать локально, поскольку настройки куки делают так, что куки будут отправляться только по HTTPS. Существуют способы настроить это, но это выходит за рамки данного вопроса.