Аутентификация: использование JWT против сеанса


123

В чем преимущество использования JWT перед сеансами в таких ситуациях, как аутентификация?

Используется ли он как отдельный подход или используется в сеансе?

Ответы:


213

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

Когда люди спрашивают об этом, часто имеют в виду: «Каковы преимущества использования JWT по сравнению с сеансами на стороне сервера ».

С сеансами на стороне сервера вам нужно будет либо сохранить идентификатор сеанса в базе данных, либо сохранить его в памяти и убедиться, что клиент всегда обращается к одному и тому же серверу. У обоих есть недостатки. В случае с базой данных (или другим централизованным хранилищем) это становится узким местом и тем, что нужно поддерживать - по сути, дополнительный запрос, который нужно выполнять с каждым запросом.

С помощью решения в памяти вы ограничиваете горизонтальное масштабирование, и на сеансы будут влиять сетевые проблемы (клиенты, перемещающиеся между Wi-Fi и мобильными данными, перезагрузка серверов и т. Д.)

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

  • Надежное хранение токена
  • безопасно транспортировать
  • Иногда бывает сложно сделать недействительными сеансы JWT.
  • Доверие претензии клиента.

Эти проблемы одинаково присущи JWT и другим механизмам сеансов на стороне клиента.

JWT, в частности, обращается к последнему из них. Это может помочь понять, что такое JWT:

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

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

Что касается безопасной транспортировки токена, то обычно ответ заключается в его отправке через зашифрованный канал, обычно httpS.

Что касается безопасного хранения токена в клиенте, вам необходимо убедиться, что злоумышленники не смогут добраться до него. Это (в основном) означает предотвращение того, чтобы JS с плохих веб-сайтов читал токен, чтобы отправить его им. Это смягчается с помощью тех же стратегий, которые используются для смягчения других видов XSS-атак.

Если вам нужно сделать JWT недействительными, определенно есть способы этого добиться. Сохранение эпохи для каждого пользователя только для пользователей, которые запросили, чтобы их «другие сеансы были завершены», - очень эффективный метод, который, вероятно, будет достаточно хорошим. Если приложению требуется признание недействительности сеанса, то идентификатор сеанса может поддерживаться таким же образом, и таблица «убитых токенов» может по-прежнему быть намного меньше, чем полная таблица пользователей (вам нужно только сохранить записи более новые, чем наибольшее допустимое время жизни токена.) Таким образом, возможность сделать токен недействительным частично сводит на нет преимущество сеансов на стороне клиента в том, что вам придется поддерживать это состояние уничтоженного сеанса. Скорее всего, это будет гораздо меньшая таблица, чем исходная таблица состояний сеанса, поэтому поиск по-прежнему более эффективен.

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

Более тонкое преимущество: поскольку JWT может нести «информацию», и клиент может получить к ней доступ, теперь вы можете начать делать некоторые умные вещи. Например, напомните пользователю, что его сеанс истечет за несколько дней до выхода из системы, дав ему возможность повторно пройти аутентификацию на основе даты истечения срока действия в токене. Все, что вы можете себе представить.

Короче говоря: JWT отвечает на некоторые вопросы и недостатки других методов сеанса.

  1. «Более дешевая» аутентификация, потому что вы можете исключить круговой обход БД (или, по крайней мере, иметь гораздо меньшую таблицу для запроса!), Что, в свою очередь, обеспечивает горизонтальную масштабируемость.
  2. Претензии на стороне клиента с защитой от взлома.

Хотя JWT не отвечает на другие вопросы, такие как безопасное хранение или транспортировка, он не представляет никаких новых проблем безопасности.

Вокруг JWT существует много негатива, но если вы реализуете ту же безопасность, что и для других типов аутентификации, все будет в порядке.

И последнее замечание: это также не файлы cookie против токенов. Файлы cookie - это механизм для хранения и передачи битов информации, а также их можно использовать для хранения и транспортировки токенов JWT.


4
Стоит отметить, что сеансы на стороне сервера также не должны хранить какую-либо информацию на сервере. Сервер может использовать клиента в качестве хранилища точно так же, как это делает JWT. Настоящая разница заключается в том, что: 1) избегают правил безопасности браузера, передавая значение в качестве заголовка запроса, отличного от заголовка cookie, и 2) имеют стандартизованный формат с JWT.
Xeoncross

1
Вы бы сказали, что безопасно хранить jwt в локальном хранилище? Если нет, то где безопасное место для его сохранения, чтобы пользователь оставался авторизованным?
Джессика

1
Да, localstorage, как правило, является наиболее правильным местом для хранения на стороне клиента. Вам действительно нужно иметь дело с XSS - я не эксперт по веб-программированию, но посмотрите на этот ответ stackoverflow.com/a/40376819/1810447 и найдите «Как защитить от XSS»
Tahaan

1
В своем комментарии вы не говорите о решении на основе кеша + токен сеанса. Мне это звучит «лучше», чем таблица JWT + «убитых токенов», потому что с этой таблицей «убитых токенов» вам в любом случае понадобится доступ к БД, который у вас будет также с сессиями + кешем (который тоже небольшой). И сохранение JWT более болезненно для реализации, чем сохранение сеансов, потому что вам нужно играть с refresh_token (так что нужно поддерживать два токена) ... Любой комментарий будет очень признателен ... особенно если у вас есть какое-то число, чтобы показать, как JWT + kill_table более эффективен, чем сеансы + кеш ;-)
tobiasBora

2
@TheTahaan localStorage не рекомендуется хранить JWT. Ссылка, которой вы поделились, также упоминает это. В этом блоге есть хорошее объяснение того, почему JWT не следует хранить в localStorage.
Харке,

40

Короткий ответ: нет.

Более длинная версия:

Я реализовал JWT для управления сеансом после прочтения этой рекомендации в документации GraphQL :

Если вы не знакомы с какими-либо из этих механизмов аутентификации, мы рекомендуем использовать express-jwt, потому что это просто без ущерба для будущей гибкости.

Реализация была действительно простой, так как лишь добавляла немного сложности. Однако через некоторое время я (как и вы) начал задаваться вопросом, в чем заключаются преимущества. Оказывается, что для JWT очень мало (или, возможно, вообще нет) в том, что касается управления сеансами, как подробно объясняется в этом сообщении в блоге:

Прекратите использовать JWT для сеансов


0

Мои два цента, которые по пути добавляют некоторый контраст знаменитому сообщению в блоге joepie91.

Учитывая, что сегодняшние (и завтрашние) приложения являются (в основном) облачными.
Существует экономическая выгода от аутентификации JWT без сохранения состояния , которая масштабируется по мере масштабирования приложения:
облачные приложения несут расходы вместе с каждым вдохом .
Эта стоимость снижается, когда пользователям больше не нужно аутентифицироваться «в хранилище сеансов».

Обработка
Работа круглосуточного магазина сессий требует денег.
В мире K8S нельзя обойтись без решений на основе памяти, так как поды недолговечны.
Липкие сеансы не будут успешными по той же причине.

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

Ввод-вывод
Некоторые облачные провайдеры взимают деньги за ввод-вывод, связанный с дисками.

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

Кластеризация хранилища сеансов
Стоимость еще больше увеличивает все вышеупомянутые затраты.


«В мире K8S нельзя обойтись без решений на основе памяти, так как контейнеры недолговечны». Не уверен, что вы имеете в виду. Redis определенно работает в среде K8S, и сбои модуля Redis достаточно часто, чтобы повлиять на ваших пользователей, кажутся очень маловероятными.
quietContest

@quietContest Я лично предпочитаю не иметь дело с вероятностью при создании программного обеспечения. Кстати, помимо стабильности решения, атака может привести к сбою программного обеспечения и перезапуску модулей, что приведет к потере сеанса. По этой причине я бы выбрал решение на основе JWT.
Эял Перри,

1
«Я лично предпочитаю не учитывать вероятность при создании программного обеспечения». Я думаю, мы все предпочли бы это, поэтому мы не должны создавать системы, которые полагаются на хранилища данных в памяти, которые никогда не выходят из строя, потому что вероятность этого кажется достаточно высокой. Что касается вашего другого момента, если у вас есть злоумышленник, который может постоянно отключать ваш экземпляр Redis, решение этого, вероятно, не требует использования JWT.
quietContest

@quietContest постоянно или раз в жизни для меня то же самое в этом аспекте. то есть хорошо организованная DDoS-атака может заставить сервер «выйти из системы». Это плохо сказывается на репутации надежности программного обеспечения. Я думаю, что Redis в любом случае является излишним для управления сеансами. Это стоит и требует масштабирования, тогда как (безопасное) хранение JWT в cookie - нет.
Эял Перри,

1
@quietContest спасибо за ваш вклад, люблю обсуждение!
Эял Перри,

0

У меня был аналогичный вопрос при выборе между JWT и токеном + кешем для аутентификации пользователя.

После прочтения этих статей мне стало ясно, что преимущества, которые обещает JWT, не опережают проблемы, которые он приносит. Таким образом, токен + кеш (Redis / Memcached) - это мой путь.

Заголовки аутентификации, JWT и сеансы - как выбрать правильный метод аутентификации для API

Методы аутентификации для API

Прекратите использовать jwt для сеансов

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.