У меня есть интерфейс netlify app.mydomain.com
и REST API django ninja api.mydomain.com
. Когда я отправляю запрос на свою конечную точку входа, API успешно возвращается с ключом доступа (который я храню в состоянии приложения) и токеном обновления в виде безопасного файла cookie только для http. Я вижу, что этот файл cookie возвращается, просматривая заголовки ответов в инструментах разработки. Однако файл cookie вообще не сохраняется в браузере. Я ответил на множество других вопросов/ответов и считаю, что реализовал все необходимое, но он все еще не работает.
Мой вызов API входа из внешнего интерфейса:
await fetch(
AUTH_URL_OBTAIN,
{
method: RequestMethod.POST,
headers: {"Content-Type": "application/json"},
body: JSON.stringify({username: formData.email, password: formData.password}),
credentials: "include",
},
);
На серверной стороне файл cookie устанавливается следующим образом:
response.set_cookie(
key = "refresh",
value=refresh_token,
expires=datetime.fromtimestamp(refresh_token_payload["exp"], timezone.utc),
httponly=True,
samesite = "none",
secure=True,
path = "/api/auth/web/token-refresh",
domain = ".mydomain.com",
)
У меня также установлены следующие настройки (замена значений переменных среды):
CSRF_TRUSTED_ORIGINS = ["https://app.mydomain.com"]
CORS_ALLOWED_ORIGINS = ["https://app.mydomain.com"]
CORS_ORIGIN_WHITELIST = ["https://app.mydomain.com"]
CORS_ALLOW_CREDENTIALS = True
Ответ на вход в систему предоставляет токен доступа (который работает, как и ожидалось — я могу прекрасно выполнять вызовы API, используя это, и иметь credentials: include
на всех fetch
запросах), а заголовки ответов приведены ниже:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://app.mydomain.com
Content-Length: 661
Content-Type: application/json; charset=utf-8
Cross-Origin-Opener-Policy: same-origin
Date: Thu, 06 Jun 2024 14:06:22 GMT
Referrer-Policy: same-origin
Server: daphne
Set-Cookie: refresh=ey...3uQ; Domain=.mydomain.com; expires=Sat, 06 Jul 2024 14:06:22 GMT; HttpOnly; Max-Age=2592000; Path=/api/auth/web/token-refresh; SameSite=none; Secure
Vary: origin
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Я сейчас в некоторой растерянности - буду очень признателен за любые советы, спасибо!
🤔 А знаете ли вы, что...
React позволяет создавать пользовательские интерфейсы для веб-приложений.
Политики безопасности браузера могут блокировать файлы cookie из/в запросы ajax. Видеть
Для API перекрестного происхождения я бы предпочел вообще не использовать файлы cookie. Представьте себе любой API-клиент, кроме браузера! Файлы cookie предназначены для отслеживания сеансов просмотра веб-сайта, а не для хранения состояния в произвольных http-клиентах.
Просто включите токен обновления в тело ответа и сохраните его также в состоянии вашего приложения.
Я реализовал множество решений такого типа, в которых файл cookie используется для включения учетных данных сообщения API и, следовательно, выдается на стороне API архитектуры.
Мне кажется, ваша проблема связана со свойством expires
файла cookie. Это приводит к тому, что файл cookie становится постоянным, и я ожидаю, что он установлен неправильно. Все остальное выглядит правильно.
Я думаю, вы можете решить свою проблему, если удалите это свойство cookie. Выполнение do также является рекомендуемым методом обеспечения безопасности и приводит к созданию файла cookie сеанса, который удаляется при закрытии браузера.
Кроме того, невозможно делать предположения о форматах токенов обновления или полезных нагрузках. Вместо этого токен обновления считается просроченным, когда вы пытаетесь использовать его в emdpoint токена сервера авторизации и получаете ответ с кодом ошибки invalid_grant
. Поэтому при использовании файлов cookie, представляющих токены, всегда учитывайте срок действия базового токена.
Это не имеет ничего общего ни с Django, ни с React. Это способ установки файла cookie.
path
может быть установлен где угодно, но доступен только на этом пути и его дочернем элементе. Таким образом, вы можете увидеть файл cookie только при посещении страницы /api/auth/web/token-refresh
Max-Age
вместо Expires
, так как это менее подвержено ошибкам. Это цитата со страницы MDN:
Expires
доступен дольше, чемMax-Age
, однакоMax-Age
менее подвержен ошибкам и имеет приоритет, если установлены оба параметра. Обоснование этого заключается в том, что когда вы устанавливаете дату и времяExpires
, они относятся к клиенту, на котором устанавливается файл cookie. Если на сервере установлено другое время, это может привести к ошибкам.
https
или localhost
.