Что не так с iframe



Довольно часто у бизнеса возникает желание запихнуть продукт в iframe и вставить так в чужой ресурс. Всё нормально до тех пор, пока не возникает вопрос аутентификации пользователя. Обычно мы сохраняем идентификатор сессии в куку, и вот тут проблема, что куки в данном случае становятся third-party, т.е. принадлежат не тому сайту, где установлен iframe, а третьей стороне.



Chrome и FF ещё можно обойти, если переставить аттрибут SameSite в none (напомнию, что по дефолту там Lax, который так же не даст отправить куку в iframe). Конечно, вам придётся повоевать с безопасниками и защитить ваше решение понизить безопасность у сессионной куки. А вот в Safari уже несколько лет как включен Intelligent Tracking Prevention (ITP) который режет куки в любом случае. Кстати, режим инкогнито в Chrome так же режет все third-party куки.



ITP блокирует все third-party cookies по умолчанию. Обойти его можно двумя способами:



- Заставить пользователя в настройках снять галочку Prevent cross-site tracking, что повлияет на все сайты

- Воспользоваться Storage Access API, с помощью которого мы явно запросим у пользователя разрешения прочитать куки с третьей стороны



Storage Access API имеет достаточно жёсткие ограничения и задействует различную неоднозначную эвристику, пытаясь догадаться, действительно ли пользователь хотел разрешить доступ. А пользователь может и не захотеть. Но, самое важное, это API закрыто в Chrome за флагом. Почему же? Скорее всего, потому, что ломает рекламный бизнес Гугл :_)



Что же делать? Вы не должны встраивать ваши сервисы в iframe as is. Вам придётся провернуть какой нибудь трюк. Например, открыть встраиваемый сервис во втором, «честном» окне, пройти аутентификацию, получить временный токен и перекинуть этот токен через postMessage в окно со страницей со встраиваемым iframe. И вот там уже перезагрузить iframe передав ему токен как get-параметр. И никаких кук.



Это не значит, что вы должны отказывать продактам в их странных желаниях. Желания продиктованы бизнесом. Но продакт не должен просить iframe. Он должен просить возможности встраивания, а вот как оно будет сделано — зависит от того, что мы сможем сделать, как разработчики.