У меня есть интерфейс 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
Я сейчас в некоторой растерянности - буду очень признателен за любые советы, спасибо!
Пробовали ли вы добавить maxAge в ответ cookie, а также SameSite: «lax» и проверить
Привет, спасибо за ваши комментарии. @Damzaky да, ты прав, другие файлы cookie настраиваются нормально. Кажется, установлен файл cookie sessionid
, который предназначен только для http. Также устанавливается файл cookie csrftoken, который не является только http. Файл cookie обновления по-прежнему не установлен. @TarunKantiwal установлен максимальный возраст, и я попробовал все варианты для samesite
.
хм, странно, а как насчет изменения имени ключа cookie с refresh
на другое, например refreshone
?
Я тоже попробовал, но все равно не сохраняется. Я вижу файл cookie в ответе, и браузер не показывает никаких ошибок, но он просто не сохраняет файл cookie. Я тоже пробовал на сафари, и там тоже не работает.
Я не уверен, но, может быть, вам стоит попробовать установить срок годности в будущем?
Токен доступа также установлен как Cookie
? Вы устанавливаете токен доступа точно так же, и он работает, но обновление не работает?
Вам следует проверить несколько моментов: 1. Path=/api/auth/web/token-refresh
: файл cookie будет сохранен только для этого пути. 2. Secure
: файл cookie будет установлен только на https 3.expires
: его следует удалить в пользу max-age
4.Domain=.mydomain.com
: файл cookie будет доступен только для субдомена
Привет всем, спасибо за все комментарии, очень ценю всю помощь. Франкфурнье, да, дата истечения срока действия установлена на будущую дату, пример, который я разместил выше, относился к файлу cookie, установленному в этот день. ChukwujiobiCanon, токен доступа хранится в состоянии приложения. Думаю, мне, возможно, тоже придется хранить токен обновления в состоянии приложения? Дуаннкс, спасибо за этот контрольный список, я просмотрю его сегодня и отчитаюсь!
@Duannx Думаю, ты справился!! Я изменил Path
на /
, и теперь устанавливается файл cookie обновления! Однако я немного смущен: почему браузер не устанавливает файл cookie, когда путь установлен на конечную точку полного обновления? Если вы хотите опубликовать свое предложение проверить путь в качестве ответа, я приму + награду!
Политики безопасности браузера могут блокировать файлы 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
.Ждал от вас ответа.
Еще раз спасибо за помощь, установка пути к /
в конце концов помогла, а также действительно интересная информация о данных Max-Age
/Expires
. Ваше здоровье!
Пожалуйста ;-)
просто любопытно, что произойдет, если вы не включите
HttpOnly
(просто установите обычный файл cookie), это сработает? Я предполагаю, что это может быть вызвано неHttpOnly