Safari отклоняет файлы cookie при вызове API на другом сервере - PullRequest
2 голосов
/ 29 января 2020

У меня есть приложение React для моего бизнеса с несколькими клиентами. Моя архитектура настроена так:

Сервер A - главный сервер приложений, обслуживает только приложение React (url = https://example.net)

Сервер B - бизнес-клиент # 1, обслуживает их слегка настроенное приложение React (url = https://example2.net)

Сервер C - Бизнес-клиент № 2, обслуживает их слегка настроенное приложение React (url = https://example3.net)

Микросервисный сервер - работает микросервис Java (url = https://api.example.net - обратите внимание, что это поддомен Сервера A)

Сервер A, B и C все разговаривают с сервером Microservice для вызовов API. При вызовах API используется вызов браузера fetch () со следующими параметрами

var options = {
   method: "{method}",
   mode: "cors",
   credentials: "include",
   headers: { "Content-Type": "application/json" }
}

Ответ сервера имеет следующий заголовок:

"Access-Control-Allow-Credentials", "true"

и использует встроенный в микросервис

enableCorsForAllOrigins()

Теперь все это прекрасно работает на Firefox, Chrome, IE и Edge. Однако он не работает в Safari (MacOS или iPhone) для сервера B или сервера C. Он отлично работает в Safari на сервере A.

Вызовы API в этой последовательности ...

POST https://api.example.net/login

GET https://api.example.net/users

В Safari первый вызов выполнен успешно, но второй вызов завершается с ошибкой 401. Ошибка 401 генерируется микросервисом, пытающимся получить атрибут Session для «currentUserId», который является нулевым. Другими словами, Safari не отправляет повар ie на сервер. Я понял, что Safari не нравится, что вызовы API направляются на базу URL, отличную от базы клиента. (Другими словами, сервер B выполняет API-вызовы к серверу A).

Для дальнейшей проверки, если пользователь запускается на сервере B, затем переходит на сервер A и выполняет вызов API (например, неверный вход в систему) ), а затем возвращается на сервер B, затем он работает для них в Safari. Похоже, что Safari просто нужно обменять Cook ie на сервере URL, чтобы он работал на любом другом сервере.

Теперь моя проблема ... как мне это исправить? Пользователи Ma c Safari и iPhone Safari на сервере B и сервере C не могут использовать приложение, поскольку их файлы cookie сеанса не отправляются на сервер. Кто-нибудь видел это раньше? У кого-нибудь есть решения? Моей первой попыткой было создание iframe на сервере B, который загружал страницу сервера A., но это не сработало.

Заранее большое спасибо!

1 Ответ

0 голосов
/ 30 января 2020

Поэтому, прочитав ссылки, предоставленные @str выше, и прочитав ссылки по этим ссылкам, я пришел к выводу, что попытка заставить его работать с помощью файлов cookie и сеансов не будет работать с Safari. Поэтому я удалил всю настройку и вместо этого пошел с JWT.

Итак, мое решение теперь таково:

POST https://api.example.net/login -> Ответ включает в себя сгенерированный сервером токен JWT с userId в нем.

JavaScript код теперь сохраняет этот JWT в SessionStorage (не повар ie, или вы столкнетесь с той же проблемой, что и при использовании сеансов).

window.sessionStorage.setItem("jwtToken", data.jwtToken);

Настройте Призывы API всегда передавать маркер JWT в качестве заголовка.

"Authorization": "Bearer " + window.sessionStorage.getItem("jwtToken")

Затем, используя библиотеку на стороне сервера, я могу извлечь токен JWT и получить из него userId.

It работает в Safari и является предпочтительным решением в настоящее время для веб-авторизации, поэтому я бы сказал go с этим решением. Недостатком является то, что хранение JWT в sessionStorage открывает пользователю возможности для атак XSS.

...