Приложение представляет собой SPA, который размещается в статическом хранилище (концептуально похожем на S3, хотя это не S3) и вообще не имеет внутреннего сервера.Предположим, это https://static.example.com/app.html
Когда пользователи посещают страницу, они могут проходить аутентификацию у внешнего поставщика, такого как Auth0 и Azure AD.Они завершают процесс аутентификации и отправляются обратно в SPA с id_token
на фрагменте URL.Например, https://static.example.com/app.html#id_token=XX
.То, что id_token
используется для вызова внешнего сервера API, передается в заголовке авторизации Bearer
.
Проблема в том, где хранить JWT на клиенте.
- Этоизвестный факт, что хранение JWT в
sessionStorage
может привести к краже токенов с помощью XSS-атак (или добавления вредоносного кода в зависимость и т. д.). - Рекомендуемый подход - хранение JWT в cookie-файле.для него установлено значение
HttpOnly
или, по крайней мере, его часть (см. раздел «Разделение файла cookie»).Тем не менее, в моем случае это невозможно, так как нет внутреннего сервера, и после аутентификации пользователи перенаправляются непосредственно в SPA, поэтому я не могу создать файл cookie HttpOnly
.Вариант этого метода - то, что OWASP рекомендует : использование «cookie-файла отпечатка пальца».Это имеет те же проблемы, так как я не могу установить cookie, который является HttpOnly
. - Другой подход, как, например, предложенный в документации Auth0 , заключается в том, чтобы сохранить JWT в памяти,Хотя это должно предотвратить кражу при большинстве (если не во всех?) XSS-атаках, это нецелесообразно, поскольку сеанс будет ограничен текущей вкладкой и не выдержит перезагрузки страницы.
Я вижу две разныеварианты, все с серьезными или потенциально серьезными недостатками:
- Сохраните токен в
sessionStorage
в любом случае, принимая на себя риск того, что в случае атак XSS (или злонамеренная зависимость, введенная через NPM) может привести к сеансамбыть украденнымЭто можно уменьшить, установив короткую продолжительность жизни токенов (например, 1 час).Хотя приложение, над которым я работаю, не хранит критически важную информацию (не банковское или подобное), ошибка в коде, позволяющая украсть сессии через XSS, была бы не очень приятной. - Реализация внутреннего серверапереместить поток аутентификации туда, возможно, даже полностью заменив JWT токенами сеанса.Однако это сделало бы приложение не статичным, и это нежелательно.
- (третий вариант, сохранение JWT в памяти, исключен из-за плохого взаимодействия с пользователем)
Чего мне не хватает?