При смене домена пользователям пришлось бы выполнять авторизацию на новом домене, потерялись бы локальные настройки приложения, пользователи SSO не могли бы авторизоваться без дополнительных настроек со своей стороны — всё это было не User friendly, возросла бы частота восстановления паролей, а часть пользователей вообще не смогли бы воспользоваться приложением сразу же.
Чтобы минимизировать потерю трафика после смены домена, нужно было провести миграцию авторизованных пользователей со старого домена на новый:
- Поддержать пользователей, которые выполняли авторизацию с помощью SSO провайдеров через старый домен.
- Передать токен авторизации пользователя со старого домена на новый.
- Передать LocalStorage с пользовательскими настройками приложения.
Передача данных и шифрование
Передавать токен было решено с помощью get-параметров, так как сайт не использовал хранилищ, в которых можно было бы сохранить токен и переиспользовать его. Передавать токен в открытую через get-параметр небезопасно, его необходимо защитить от перехвата. У нас было два способа шифрования: OpenSSL и Mcrypt. Mcrypt давно не обновлялся, медленнее шифрует данные по сравнению с OpenSSL, а лишняя нагрузка на сервер нам не нужна. Поэтому мы шифровали токен с помощью OpenSSL.
Однако полученный хэш всё равно можно было перехватить и использовать снова. Для того, чтобы токен нельзя было переиспользовать, мы добавили параметр «дата шифрования», тем самым хэш был действителен в течении 10 секунд — этого времени хватало с запасом для выполнения всех операций. Также мы добавили замену ключа шифрования раз в 12 часов, ключ хранился в Vault и был синхронизирован между сайтами.
Получившийся хэш передавался в виде get-параметра и был дополнительно обработан с помощью url_encode для безопасной передачи через URL, так как символы могли экранироваться или испортить структуру адреса.
Структура хэша:
url_encode(OpenSSL({ 'token': 'токен', 'date': 'Дата шифрования', 'additional_values': ['param', 'param'] }))
LocalStorage доступен только через JavaScript. Для решения этой задачи был выбран интерфейс postMessage и iframe, что позволяло безопасно отправлять кроссдоменные запросы. Данные в LocalStorage были сконвертированы в строки с помощью JSON.stringify() и переданы на домен miro.com, где они конвертировались обратно и записывались в LocalStorage домена miro.com.
Схема работы с описанием всех шагов

Схема в удобном для просмотра виде.
Пользователи могли попасть в сервис двумя путями: через старый домен realtimeboard.com (например, из закладок) или через новый miro.com (например, через рекламу).
Если пользователь заходил на старый домен:
- После открытия любой страницы realtimeboard.com выполняется шифрование токена пользователя, даты создания и дополнительной служебной информации.
- После шифрования происходит редирект на miro.com/migration/?data={hash} с передачей hash как Get параметр. Сам токен и служебная информация удаляются на старом домене, т.к они больше были не нужны.
- На новом домене miro.com выполняется расшифровка хэша, проверка на то, что он не просрочен, и установка токена пользователя, если он был передан.
- Проставляется флаг migrationToken, чтобы не выполнять миграцию снова.
- Для миграции LocalStorage мы проверяли наличие куки migrationLocalstorage. Если куки не существовало, выполнялся рендеринг страницы с JS-скриптом, который открывал в iFrame страницу relatimeboard.com/localstorage/ и принимал сообщения от неё с помощью postmessage После окончания миграции пользователя редиректило на страницу, которую он пытался открыть первый раз.
Если пользователь заходил сразу на новый домен miro.com, выполнялась проверка на прохождение пользователем миграции токена и LocalStorage. Если пользователь уже выполнил миграцию, то он оставался на домене miro.com. Если не выполнил — происходил редирект на realtimeboard.com для получения токена (для этого мы хранили в куках два флага: migrationToken и migrationLocalstorage).
Эта схема так же хорошо работала для пользователей с SSO, которые выполнили авторизацию на старом домене realtimeboard.com. Был добавлен список маршрутов, которые работали без миграции токена на новый домен. В них входил маршрут для SSO, который выполнялся как обычно и выполнял редирект на /app/ или /login/ в зависимости от состояния своей работы, после чего снова подключался механизм миграции токена.
Вывод
На исследование и подготовку я потратил месяц, ещё месяц на обкатку (параллельно занимался другими проектами). Благодаря этому решению мы смогли мигрировать авторизованных пользователей со старого домена на новый и поддержать пользователей, которые использовали SSO для авторизации через старый домен.
ссылка на оригинал статьи https://habr.com/ru/company/miro/blog/509052/
Добавить комментарий