Совместное использование хранилища sessionStorage для передачи данных между вкладками для безопасной аутентификации с несколькими вкладками.
Я создал механизм, который будет использовать безопасный характер хранилища сеансов браузера sessionStorage или хранилища памяти memoryStorage для аутентификации и по-прежнему позволит пользователю открывать несколько вкладок без необходимости каждый раз повторно входить в систему.
Обновление информации о соответствующем механизме хранения браузера.
- localStorage ~5 МБ, хранение без ограничения по времени, до тех пор, пока пользователь не удалит это вручную.
- sessionStorage ~5 МБ, хранение на всю жизнь текущей вкладки.
- cookie ~4 КБ, может быть сохранен до бесконечности.
- session cookie ~4 КБ, удаляется, когда пользователь закрывает браузер (не всегда удаляется).
Безопасное кэширование токенов сессии.
При работе с критическими платформами ожидается, что сеанс завершается, когда пользователь закрывает вкладку.
Чтобы поддержать это, никогда не следует использовать файлы cookie для хранения каких-либо конфиденциальных данных, таких как токены аутентификации. Даже сессионных файлов cookie будет недостаточно, так как они будут продолжать жить после закрытия вкладки и даже после полного закрытия браузера.
(В любом случае мы должны рассмотреть вопрос о том, чтобы не использовать файлы cookie, поскольку у них есть другие проблемы, которые необходимо решить, т. е. CSRF.)
Это оставляет нам возможность сохранить токен в памяти или в хранилище сеансов. Преимущество sessionStorage заключается в том, что он будет сохраняться на разных страницах и обновляться браузером. Таким образом, пользователь может перейти на другие страницы и/или обновить страницу и по-прежнему оставаться в системе.
Хорошо. Мы сохраняем токен в хранилище сеансов, отправляем его в виде заголовка с каждым запросом на сервер для аутентификации пользователя. Когда пользователь закрывает вкладку – она исчезает.
Но как насчет нескольких вкладок?
Довольно часто даже в одностраничном приложении пользователь захочет использовать несколько вкладок. Вышеупомянутая мера безопасности по сохранению токена в хранилище сеансов создаст некоторый плохой UX в виде запроса пользователя на повторный вход в систему с каждой открываемой им вкладкой. Правильно, sessionStorage не является общим для всех вкладок.
Общий доступ к хранилищу сеансов между вкладками с помощью событий localStorage.
Я решил эту проблему с помощью событий localStorage.
Когда пользователь открывает новую вкладку, мы сначала спрашиваем любую другую открытую вкладку, есть ли у него уже sessionStorage для нас. Если откроется какая-либо другая вкладка, она отправит нам sessionStorage через событие localStorage, мы продублируем его в sessionStorage.
Данные sessionStorage не останутся в локальном хранилище даже на 1 миллисекунду, поскольку они будут удалены в том же вызове. Данные передаются через полезную нагрузку события, а не через само локальное хранилище.
Нажмите кнопку “Set the sessionStorage”, а затем откройте несколько вкладок, чтобы увидеть, что хранилище сеансов является общим.
Почти идеально.
Теперь у нас есть, вероятно, самый безопасный способ кэширования токенов сеанса в браузере и без ущерба для работы с несколькими вкладками. Таким образом, когда пользователь закрывает вкладку, он точно знает, что сеанс закончился. Или это так?!
И Chrome, и Firefox оживят хранилище сеансов, когда пользователь выберет “Повторно открыть закрытую вкладку” и “Отменить закрытие вкладки” соответственно.
Черт возьми!
Safari делает это правильно и не восстанавливает sessionStorage (проверено только с этими 3 браузерами).
Для пользователя единственный способ быть полностью уверенным в том, что sessionStorage действительно исчез, - это открыть тот же веб-сайт напрямую и без функции “открыть закрытую вкладку”.
Это до тех пор, пока Chrome и Firefox не устранят эту ошибку. (моя интуиция подсказывает мне, что они назовут это “особенностью“).
Даже с этой ошибкой использование sessionStorage по-прежнему безопаснее, чем файл session-cookie или любая другая альтернатива. Если мы хотим сделать его идеальным, нам нужно будет реализовать тот же механизм, используя память вместо sessionStorage. (onbeforeunload и тому подобное тоже могут работать, но не будут такими надежными и будут очищаться также при обновлении. window.name почти хорошо , но он слишком стар и не имеет междоменной защиты).
Совместное использование хранилища памяти между вкладками для безопасной аутентификации с несколькими вкладками.
Так… это будет единственный реальный безопасный способ сохранить токен аутентификации в сеансе браузера и позволит пользователю открывать несколько вкладок без необходимости повторного входа в систему.
Закройте вкладку, и сеанс исчезнет – на этот раз по-настоящему.
Недостатком является то, что при наличии только одной вкладки обновление браузера заставит пользователя повторно войти в систему. Безопасность имеет свою цену, очевидно, что это не рекомендуется для любого типа систем.
Установите хранилище памяти memoryStorage и откройте несколько вкладок, чтобы оно было общим для них. Закройте все связанные вкладки, и маркер исчезнет навсегда (MemoryStorage - это просто объект javascript).
*
P.S.* Излишне говорить, что управление сеансами и истечение срока действия также должны обрабатываться на стороне сервера.