Нужно ли хранить токены в файлах cookie, локальном хранилище или сеансе? - PullRequest
0 голосов
/ 18 января 2019

Извините, может быть, это вопрос, который задавали многие другие, но я действительно запутался, потому что некоторые ссылки имеют много разных способов.

Я использую React SPA, Express, Express-session, Passport, JWT

, поэтому я не совсем понимаю, что такое Cookies, Session и JWT / Passport.

Многие веб-сайты используют куки для хранения токенов корзины.До сих пор я сохранял данные корзины покупок на основе идентификатора сеанса без добавления файлов cookie.

Поэтому, когда пользователи посещают мой веб-сайт, я сопоставляю их с их req.sessionID, а затем извлекаю данные вбазы данных, такие как корзины покупок и сеанс пользователя.

, поэтому мой вопрос: нужно ли мне хранить куки? потому что я могу получить к ним доступ через req.sessionID, чтобы получить необходимые данные.

И второй

Я произвел аутентификацию с использованием passport-google-oauth20. После успешного входа в систему данные сохраняются в сеансе.и чтобы отправить его клиенту, я должен отправить его через запрос URL ?token='sdsaxas'.

в этом случае я получаю большую разницу во мнениях.кто-то сохранил его в локальном хранилище, а кто-то сохранил в cookie-файлы, преобразовав его в токен с помощью JWT.

 jwt.sign(
        payload,
        keys.jwt.secretOrPrivateKey, 
        {
            expiresIn:keys.jwt.expiresIn // < i dont know what is this expired for cookies or localstorage ?
        }, (err, token) => {

            res.redirect(keys.origin.url + "?token=" + token);
        });

Вывод: все связано с сеансом, поэтому я могу сделатьэто все с sessionID?без cookie-файлов или локального хранилища

Только путем выборки один раз или обновления каждой страницы и извлечения данных, а затем сохранения в избыточном количестве, поскольку я использую React SPA

Ответы [ 3 ]

0 голосов
/ 15 февраля 2019

HTTP - это протокол без сохранения состояния. Прочтите этот ответ для более подробной информации, но, по сути, это означает, что HTTP-серверы, такие как ваш веб-сервер, не хранят никакой информации о клиентах после срока действия одного запроса. Это проблема для веб-приложений, потому что это означает, что вы не можете вспомнить, какой пользователь вошел в систему.

Куки были изобретены как решение этой проблемы. Куки-файлы - это текстовые данные, которые клиент и сервер отправляют туда и обратно по запросу каждый . Они позволяют эффективно поддерживать данные о состоянии приложения, так как клиент и сервер договариваются о том, что они запоминают при каждом общении.

В основном это означает, , что вы не можете иметь сеанс без куки . должен быть файлом cookie, в котором хранится как минимум идентификатор сеанса, чтобы вы могли узнать, какой пользователь в данный момент вошел в ваше приложение, просмотрев сеанс. Вот что делает express-session: документация для основного метода session явно отмечает, что идентификатор сеанса хранится в cookie.

поэтому мой вопрос: нужно ли мне хранить куки? Потому что я могу получить к ним доступ через req.sessionID, чтобы получить необходимые данные.

Вам не нужно хранить куки. Экспресс-сессия сделает это за вас. Ваше приложение в целом нуждается в хранении файла cookie; без него у тебя не было бы req.sessionID, чтобы искать.

0 голосов
/ 15 февраля 2019

Согласно моему опыту, просто храните токен в localStorage.

LocalStorage

может хранить информацию до 5 МБ. Вам не нужно спрашивать у пользователя разрешения на сохранение токена в localStorage.

Единственная проблема заключается в том, поддерживает ли целевое устройство API-интерфейс localStorage.

Проверьте здесь: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

Широко поддерживается. Но по моему опыту, если у вас есть приложение ios, и в этом приложении есть html-страница, в которой пользователю предлагается сохранить токен (также называемый webview), API-интерфейс localStorage не может быть распознан и выдает ошибку.

Решение заключается в том, что я просто помещаю токен в URL и передаю его каждый раз. В веб-просмотре URL не виден.

Cookie:

Это очень старый стиль для хранения информации локально. Хранение в cookie относительно невелико, и вам необходимо запросить разрешение пользователя для сохранения токена в cookie.

Файлы cookie отправляются с каждым запросом, поэтому они могут ухудшить производительность (особенно для мобильных соединений для передачи данных). Современные API для клиентского хранилища - это API веб-хранилища (localStorage и sessionStorage) и IndexedDB. (https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)

Не хранить токен в sessionStorage или redux.

Данные, сохраненные в sessionStorage, будут потеряны, если вкладка закрыта. Если пользователь случайно закрыл вкладку, токен теряется, и сервер не сможет идентифицировать текущего пользователя. Токен, сохраненный в redux, не отличается от других js-файлов. Излишнее хранилище - это просто еще один JS-файл. информация, сохраненная в избыточном коде, теряется при каждом обновлении страницы.

В заключение

Большую часть времени токен хранится в localStorage, если используется современный стиль. В определенных сценариях вы можете хранить токен в cookie и иногда помещать его в URL. Но никогда не храните в сессии.

Надеюсь, это поможет.

0 голосов
/ 18 января 2019

Этот ответ основан на подходе без сохранения состояния и поэтому не говорит о традиционном управлении сессиями

Вы задали два совершенно разных вопроса:

  1. Корзина - которая больше связана с бизнес-функциями
  2. OAuth 2 & JWT - что связано с безопасностью и аутентификацией

Как пользователь веб-сайта электронной коммерции, я ожидаю, что любой товар, который я добавляю в свою корзину для покупок со своего мобильного устройства во время поездок на рабочее место, должен быть доступен в корзине при входе на веб-сайт с моего компьютера после достигнув дома. Поэтому данные корзины должны быть сохранены во внутренней БД и связаны с моей учетной записью.

Когда речь идет об аутентификации с использованием OAuth 2.0, токен доступа JWT и / или токен обновления необходимо хранить где-то на клиентском устройстве, поэтому, когда пользователь аутентифицирует себя, предоставляя учетные данные для входа, ему не нужно предоставлять его учетные данные снова, чтобы перемещаться по сайту. В этом контексте локальное хранилище браузера, сессионное хранилище и файлы cookie являются допустимыми параметрами. Однако обратите внимание, что здесь файл cookie не связан ни с одним сеансом на стороне сервера. Другими словами, cookie не хранит идентификатор сессии. Файл cookie просто используется в качестве хранилища для токена доступа, который передается на сервер при каждом http-запросе, и затем сервер проверяет токен с помощью цифровой подписи, чтобы убедиться, что он не был подделан и срок его действия не истек.

Хотя все три варианта хранения для доступа и / или обновления токенов популярны, cookie-файл представляется наиболее безопасным при правильном использовании.

Чтобы лучше это понять, я рекомендую прочитать это и это вместе со спецификацией OAuth 2.0.

Обновление от 16 февраля 2019

Я уже говорил ранее, что cookie - это наиболее безопасный вариант. Я хотел бы уточнить это здесь.

Причина, по которой браузеры localStorage и sessionStorage не обеспечивают достаточной безопасности для хранения токенов аутентификации, заключается в следующем:

  1. Если происходит XSS, вредоносный скрипт может легко прочитать токены оттуда и отправить их на удаленный сервер. На удаленном сервере или злоумышленнике не возникнет проблем с выдачей себя за пользователя-жертву.

  2. 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 заголовка ответа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...