Токен 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. Существуют способы настроить это, но это выходит за рамки данного вопроса.

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