Safari 13+ iframe блокирует файлы cookie CORS

9

Использование Safari не позволяет устанавливать файлы cookie в фреймах доменов, отличных от родительского, и проклятые заголовки CORS на стороне сервера.

Чтобы уточнить: пользователь находится на domainA.com. Iframe для domainB.com открыт и пытается аутентифицировать пользователя на domainB.com внутри iframe. Заголовок Set-Cookie возвращается с сервера внутри iframe domainB.com со всеми необходимыми заголовками, но Safari не отправляет его обратно при последующих вызовах.

Старый обходной путь выполнял отправку формы из iframe и устанавливал cookie в ответе. Я предполагаю, что им понравилось то, что пользователь нажимал что-то, чтобы отправить форму. Вам нужно будет опросить файл cookie, чтобы узнать, когда ответ вернулся, поскольку отправленные формы не имеют обратных вызовов, а в случае файлов cookie HttpOnly вы не можете, но, эй, это сработало! Пока этого не произошло.

Затем, более поздний обходной путь - перенаправление пользователя на домен iframe в совершенно новом окне / вкладке, установка там случайного файла cookie, и с этого момента этот поддомен был «доверенным» внутри iframe. Опять же, для открытия нового окна / вкладки требовался щелчок, и даже была визуальная индикация открытия новой вкладки. Большая безопасность, такие стандарты.

И теперь, начиная с Safari 13 - больше нет обходного пути. Нет более безопасной настройки iframe cookie 🤬

Любая другая схема аутентификации нам не подходит (например, заголовок Auth-X). Нам нужно использовать безопасный HttpOnly cookie, так как мы не хотим, чтобы этот токен был каким-либо образом доступен для клиентской части javascript.

Чтобы было ясно, все прекрасно работает в любом другом браузере.

Соответствующий WebKit Bugzilla

У кого-нибудь есть предложения?

Редактировать:

Спасибо за ссылку @tomschmidt, это похоже на правильное направление. Я попытался использовать API-интерфейс Apple Storage Access, но, к сожалению, хотя я запрашиваю доступ перед инициализацией логики входа в систему с помощью API:

requestStorageAccess = async() => {
    return new Promise(resolve => {
      //@ts-ignore
      document.requestStorageAccess().then(
        function () {
          console.log('Storage access was granted');
          resolve(true);
        },
        function () {
          console.log('Storage access was denied');
          resolve(false);
        }
      );    
    });
  }


const storageAccessGranted = await requestStorageAccess();
console.log(storageAccessGranted) // prints 'true'
await login();

Тем не менее файлы cookie, полученные в ответе API / login, не отправляются при последующих вызовах API :(

Том Теман
источник
Убедитесь, что это срабатывает только при явном взаимодействии с iframe, например onclick.
Томшмидт
1
Да, вот как я это сделал. Ознакомьтесь с проблемой webzit bugzilla, с которой я связан, я думаю, что это настоящая ошибка в конце Safari: /
Tom Teman
Проблема не в том, что куки не отправляются. Если вы запрашиваете доступ к хранилищу, существующие куки отправляются на сервер. Проблема в том, что любые новые куки не хранятся вообще, поэтому их не нужно отправлять.
Мэтт Косентино
@MattCosentino да, именно это я и имел в виду - «куки, полученные в ответе / login API» - это новые куки, которые отправляются обратно в ответе заголовка Set-Cookie на домен iframe, но следующий вызов из домена iframe не включает эти куки в запросе. Так что да, правильнее будет сказать, что корень проблемы в том, что в этом сценарии в браузере не хранятся новые файлы cookie.
Том Теман

Ответы:

1

Я думаю, что мог бы найти решение: API доступа к хранилищу Apple: https://webkit.org/blog/8124/introduction-storage-access-api/

tomschmidt
источник
Эй, спасибо за идею, но я боюсь, что это не сработало (проверьте мой ответ редактировать)
Том Теман
1
У меня также есть та же проблема с сафари. 13. Есть ли обходной путь?
Нирошана
0

Таким образом, обходной путь все еще работает, пока новое окно хранит куки, которые вы хотите сохранить. Iframe по-прежнему не может хранить свои собственные куки. В моем случае все, что мне было нужно, это cookie сессионного идентификатора. Итак, я открываю небольшое всплывающее окно, когда пользователь предоставляет доступ к хранилищу. Он получает и сохраняет cookie идентификатора сессии, закрывает и перезагружает iframe. Затем iframe имеет доступ к cookie-идентификатору сеанса и отправляет его в последующих запросах. Я думаю, что это только временно, похоже, они собираются удалить доступ к хранилищу из всплывающих окон в будущем. Возможно, они исправят iframe, не имея возможности хранить куки к тому времени.

Мэтт Косентино
источник
Мэтт, я использовал подобное решение с всплывающим окном, которое работает на настольном Safari 13.1, но тестирование на iPad Safari 13.4 не работает. Удалось ли вам заставить это работать на iPad? Thnx
teamdane