Этот ответ основан на подходе без сохранения состояния и поэтому не говорит о традиционном управлении сессиями
Вы задали два совершенно разных вопроса:
- Корзина - которая больше связана с бизнес-функциями
- OAuth 2 & JWT - что связано с безопасностью и аутентификацией
Как пользователь веб-сайта электронной коммерции, я ожидаю, что любой товар, который я добавляю в свою корзину для покупок со своего мобильного устройства во время поездок на рабочее место, должен быть доступен в корзине при входе на веб-сайт с моего компьютера после достигнув дома. Поэтому данные корзины должны быть сохранены во внутренней БД и связаны с моей учетной записью.
Когда речь идет об аутентификации с использованием OAuth 2.0, токен доступа JWT и / или токен обновления необходимо хранить где-то на клиентском устройстве, поэтому, когда пользователь аутентифицирует себя, предоставляя учетные данные для входа, ему не нужно предоставлять его учетные данные снова, чтобы перемещаться по сайту. В этом контексте локальное хранилище браузера, сессионное хранилище и файлы cookie являются допустимыми параметрами. Однако обратите внимание, что здесь файл cookie не связан ни с одним сеансом на стороне сервера. Другими словами, cookie не хранит идентификатор сессии. Файл cookie просто используется в качестве хранилища для токена доступа, который передается на сервер при каждом http-запросе, и затем сервер проверяет токен с помощью цифровой подписи, чтобы убедиться, что он не был подделан и срок его действия не истек.
Хотя все три варианта хранения для доступа и / или обновления токенов популярны, cookie-файл представляется наиболее безопасным при правильном использовании.
Чтобы лучше это понять, я рекомендую прочитать это и это вместе со спецификацией OAuth 2.0.
Обновление от 16 февраля 2019
Я уже говорил ранее, что cookie - это наиболее безопасный вариант. Я хотел бы уточнить это здесь.
Причина, по которой браузеры localStorage
и sessionStorage
не обеспечивают достаточной безопасности для хранения токенов аутентификации, заключается в следующем:
Если происходит XSS, вредоносный скрипт может легко прочитать токены оттуда и отправить их на удаленный сервер. На удаленном сервере или злоумышленнике не возникнет проблем с выдачей себя за пользователя-жертву.
localStorage
и sessionStorage
не распределяются между поддоменами. Таким образом, если у нас есть два SPA, работающих на разных поддоменах, мы не получим функцию единого входа, потому что токен, сохраненный одним приложением, не будет доступен для другого приложения в организации. Есть некоторые решения, использующие iframe
, но они больше похожи на обходные пути, чем на хорошее решение. И когда заголовок ответа X-Frame-Options
используется, чтобы избежать атак с использованием ClickJacking с помощью iframe
, любое решение с iframe
не подлежит сомнению.
Эти риски, однако, могут быть уменьшены с помощью отпечатка пальца (как упомянуто в OWASP JWT Cheat Sheet ), который, в свою очередь, также требует cookie.
Идея отпечатка пальца состоит в том, чтобы генерировать криптографически сильную случайную строку байтов. Строка Base64 необработанной строки будет затем сохранена в файле cookie HttpOnly
, Secure
, SameSite
с префиксом имени __Secure-
. Надлежащие значения для атрибутов домена и пути должны использоваться в соответствии с бизнес-требованиями. Хэш строки SHA256 также будет передан в заявке JWT. Таким образом, даже если атака XSS отправляет токен доступа JWT удаленному серверу, управляемому злоумышленником, он не может отправить исходную строку в файле cookie, и в результате сервер может отклонить запрос на основании отсутствия файла cookie. Файл cookie HttpOnly
не может быть прочитан сценариями XSS.
Поэтому, даже когда мы используем localStorage
и sessionStorage
, мы должны использовать cookie, чтобы обеспечить его безопасность. Кроме того, мы добавляем ограничение субдомена, как упомянуто выше.
Теперь единственное беспокойство по поводу использования cookie для хранения JWT - это CSRF-атака. Поскольку мы используем SameSite
cookie, CSRF смягчается, потому что межсайтовые запросы (AJAX или просто через гиперссылки) невозможны. Если сайт используется в каком-либо старом браузере или некоторых других не очень популярных браузерах, которые не поддерживают файл cookie SameSite
, мы все равно можем уменьшить CSRF, дополнительно используя файл cookie CSRF с криптографически сильным случайным значением, так что каждый запрос AJAX читает файл cookie. значение и добавьте значение cookie в пользовательский заголовок HTTP (за исключением запросов GET и HEAD, которые не должны изменять состояние). Поскольку CSRF не может читать что-либо из-за одной и той же политики происхождения и основан на использовании небезопасных методов HTTP, таких как POST, PUT и DELETE, этот файл CSRF уменьшит риск CSRF. Этот подход использования файла cookie CSRF используется всеми современными средами SPA. Угловой подход упоминается здесь .
Кроме того, поскольку cookie - httpOnly
и Secured
, сценарий XSS не может его прочитать. Таким образом, XSS также смягчается.
Также стоит упомянуть, что XSS и внедрение сценариев могут быть дополнительно смягчены с помощью соответствующего content-security-policy
заголовка ответа.