Я много читал о том, что нельзя сохранять токены в хранилище пользовательского агента, и я согласен с упомянутыми рисками. Но, просматривая некоторые примеры быстрого запуска Auth0, я вижу, что токены сохраняются в сеансе и используются файлы cookie сеанса для их отслеживания.
Другие упоминают о сохранении фактического токена в виде файла cookie httpOnly с меньшими рисками.
Мои вопросы:





Поддержание сеанса применимо только тогда, когда у вашего приложения есть серверная часть. С точки зрения SPA хранение токена в localstorage допустимо и относительно безопасно. Современные браузеры имеют возможность защиты от взлома по сравнению с другими средствами.
Если у вас есть серверная часть, сопоставление токена доступа с сеансом лучше, чем сохранение его в файле cookie. Также одним из преимуществ, которые вы получаете, является возможность получить токен обновления, который можно хранить в бэкэнде.
Наличие файла cookie означает потерю безгражданства. Файлы cookie предназначены для поддержания состояния между сервером и клиентом. Для поддержания сеанса требуются ресурсы сервера, но я не думаю, что вам нужно сильно беспокоиться об этом. Масштабирование должно выполняться в соответствии с вашими конкретными требованиями.
Помните, что функциональность опять же строится на файлах cookie. Это функциональность, предоставляемая сервером авторизации. Представьте, что ваш браузер запоминает ваш статус входа в Facebook. Он использует файлы cookie, и вашему приложению не нужно об этом беспокоиться!
Аси Кавинду написал: localStorage — хорошее место. Если вы хотите защитить приложение от XSS-атак, используйте Политика безопасности контента, чтобы браузер выполнял только ваш код JavaScript. Существует недавний RFC о лучших практиках для OAuth 2.0 и браузерные приложения, так что вы можете проверить его.
Если вы хотите сохранить состояние (сеанс) на своем бэкэнде с несколькими бэкэнд-узлами (кластером), вы можете использовать некоторое общее хранилище данных, такое как база данных или Hazelcast. Архитектура сохраняет состояние так же, как один внутренний узел с сеансом в памяти.
Если у вас есть сеанс на вашем бэкэнде и файл cookie, вам больше не нужен токен доступа, поскольку ваш SPA вызывает только ваш бэкэнд, и токен будет служить той же цели, что и идентификатор сеанса из файла cookie.
Функциональность «запомнить меня» может быть реализована с помощью файла cookie либо у вашего поставщика аутентификации (вероятно, лучший выбор с точки зрения безопасности), либо в вашем собственном приложении.
Выбор архитектуры обычно представляет собой компромисс между простотой и масштабируемостью. Если вы только начинаете разрабатывать приложение и не знаете, что выбрать, я бы выбрал простоту, потому что даже если вы захотите изменить его позже, рефакторинг должен быть проще.
Так что это на самом деле то, что я делаю, но потом многие выразили беспокойство по поводу использования localStorage. Спасибо за подробные ответы.
Вы также можете использовать sessionStorage, который не сохраняется при перезапуске браузера и зарезервирован для одной вкладки браузера. Это может быть более подходящим, если вы хотите хранить только кратковременные данные и не делиться ими между вкладками браузера.
Мое приложение представляет собой SPA, подключающееся к внутреннему API, поддерживаемому мной. Я хочу, чтобы пользователя запомнили, раньше я сохранял его токен в localStorage. Но теперь я боюсь XSS, поэтому я создаю лучший сервер аутентификации. Если я использую сеансы, он будет привязан к одному экземпляру на случай, если я захочу его масштабировать. Мне придется поддерживать сеансы, используя некоторую память или постоянную базу данных. В основном я искал хороший архитектурный подход.