Pull to refresh

Comments 23

  • Легче горизонтально масштабировать (чем что?)

  • Легче использовать (чем что?)

  • Более гибкие (чем что?)

  • Более безопасные (чем что?)

Автор пытается сравнить палец с какой-то абстрактной жопой. Причем в самом начале идет утверждение, что не надо сравнивать JWT и куки, но при этом по всей статье создается ощущение, что сравнение производится именно такое. Пример:

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

И что такое "стандартная сессия", кстати?

И преимущества и недостатки сравниваются с... да хрен его знает, с чем сравниваются. Я понимаю, что это перевод, но перевод какой-то мутной фигни, чесслово.

Вся суть статьи автора, сводится к тому, что не нужно использовать Stateless JWT. Берешь Stateful JWT и почти все проблемы исчезают.... Зачем брать, что-то плохое, если об этом заранее известно, когда есть решения лучше.

В целом - да, удачное резюме.
Тем не менее, до сих с какой-то периодичностью я слышу эти же самые аргументы в пользу отказа от серверных сессий в пользу вшивания данных в JWT, и даже такой уровень рассмотрения помогает людям прийти в себя и посмотреть на альтернативы.
Ну а раз это уже кому-то помогло, может, и еще кому поможет? :)

Просто надо делать акссес-токены короткоживущими (20 минут), но тогда мы будем платить тем, что нельзя будет моментально токен отозвать (как минимум 20 минут будет жить), но и права видимо не надо давать большие через них.

  1. Уже было.

  2. PASETO.

  3. Да, можно сессии и в Redis хранить. А можно и не хранить, а Redis считать кешем, которые могут обнулиться в любой момент, сессии хранить локально, декодируя токен по необходимости (если пользователь переключился с одного инстанса на другой), а обычно беря его только как строку id-сессии.

Какая по вашему мнению альтернатива для мобильных приложений с access и refresh токенам? Каждый раз клиенту вводить пароль для входа в приложение при перехагрузке смартфона, или выгрузки из памяти приложения?

Proof-of-Possession (PoP) Tokens

Device Attestation + OAuth DPoP

MTLS

WebAuthn + FIDO2

Нейронки так отвечают

Так в статье же указано, что можно использовать ту же самую сессию, что хранится в куках. Принципиально такой подход ничем не отличается от jwt. На клиенте хранится какой-то идентификатор сессии, который передается в заголовке.

Использовать не jwt, а опак токен. А его уже разменивать на jwt внутри инфры.

Спасибо за перевод.
Хотел бы узнать мнения автора и заинтересованных по поводу применения stateless-JWT в следующем кейсе: CRUD-продукт с RBAC, в котором UI (возможные вкладки, кнопки) может меняться исходя из набора прав у определенного пользователя. Стек - React (CSR) + бэкэнд. Есть требование к производительности 'нужно чтобы работало очень быстро в глазах пользователя'. До бэкэнда со стороны пользователя всегда пинг 100+, особенность расположения такая.
По опыту, при использовании такого стека вместе с сессиями, возникала проблема - при открытии каждой react-странички нужно делать запрос на бэк и узнавать у него по сессионной куке что за пользователь сейчас сидит, и есть ли у него права на просмотр текущей страницы, что ему вообще можно видеть. Если все ок, то уже после этого летят запросы на эндпоинты отрисовки страницы.
Если даже опустить вопрос производительности такого решения (минимум 2 синхронных API запроса на отрисовку страницы), то возникало кучи проблем связанных с редиректами при протухании сессии, кэшами редиректов в браузере.
В такой ситуации использование JWT с информацией о правах с коротким access-токеном и длинным refresh-токеном избавило бы от необходимости долбить бэкэнд на предмет текущей ситуации по правам.
SSR через Next JS и сессии на его стороне уж очень не хочется завозить, видится лишним усложнением стека только ради сессий.

Теперь вопрос: оправдано ли здесь использование JWT в таком виде? Если делать по другому, то какие варианты можно рассмотреть? Возможно просто стоит использовать Next?

реакт и так работает с запросами через API, если бек стоит через фреймоврк JS то думаю сначала нужно составить хорошую RBAC затем сделать Secure Object Reference чтобы не воникало Information Disclosure или тот же IDOR, и использовать хороший и сложный(в плане сложности необратимости) алгоритм для того чтобы каждый обьект имел уникальный айди или чтото того рода, а в плане произовдительности хорошо сочетается реакт и некст и опенграв на беке как рест (личное мнение)

Мы в своё время делали очень просто. У нас в теле страницы index.html в хидере был блок script в котором, условно, была переменная которая называлась permissions = %$userPermissions$%, на nginx был написал lua скрипт, который перед отдачей этой страницы делал внутренний запрос на получение пермишенов и тупа реплейсил этот макрос куском json. Приложение на фронте сразу инитилось с этой переменной. Ssr мы не применяли. Получалось что никаких доп запросов с фронта не было и приложение получало всю необходимую инфу при инициализации.

Под "стандартной сессией" автор наверное понимает обычный токен без вшитой в него информации. Аутентификация пользователя идет после запроса ко внешнему хранилищу (база, редис), затем мы получаем доп данные снова из хранилища. Истечение сессии тоже хранится где-то.

Jwt это подписанный на сервере payload по юзеру с некими стандартными полями для контроля протухания. Если хочется сэкономить на запросах в хранилище, это хороший вариант. Если же сам jwt токен начинают хранить в базе, и эти запросы все равно требуются (если хочется иметь возможность отменять рабочие сессии, например), то плюсы резко уменьшаются.

По-моему автор вообще не понимает как работает keycloak.

Вы не можете заставить пользователя прислать вам jwt, ее должен вам прислать кто-то. И это keycliak proxy.

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

Дальше элементарный вывод. Сессионные данные могут храниться или на клиенте или на прокси/keycloak, или в приложении/кэш/бд. Комбинации возможны! Вы можете из приложения создать хоть сесионную, хоть перманентную куку, рядом с кукой прокси.

Jwt совсем для другого и чаще всего она приходит как данность, управлять приложение ей не может вообще никак.

Просто используйте обычные сессии

Интересно было бы узнать у непосредственного автора, что здесь имеется ввиду под обычной сессией... Т.к. JWT сравнивается то ли с куки, то ли с чем-то ещё, ввиду чего возникает непонимание, когда прокритиковали, но взамен не предложили. Кроме единственной строчки про express-session, однако и она просто хранит ID, а данные предлагает хранить у себя на сервере. И чем же тогда это отличается от stateful JWT?..

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

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

От stateful jwt это действительно мало чем отличается (что автор в тексте отметил), кроме того, что фреймворк (или библиотеки) зачастую дают эту цепочку как готовую ("получить идентификатор - подписать его - оформить в виде куки") либо делают за вас часть этой цепочки в виде подписи.
И тогда вопрос целесообразности. Если уже есть готовый способ получить идентификатор сессии и подписать его через HMAC, то зачем тогда JWT?
При этом верно и обратное, если библиотека оперирует jwt изначально (как jjwt, например), то можно и его использовать, это ничему не противоречит.

Основной поинт в том, чтобы не превращать этот токен в хранилище.

Спасибо, теперь стало лучше понятно) Недавно начал заниматься веб-разработкой, и вопросы безопасности также интересуют, потому и изучаю, что есть, когда лучше использовать и т.п. В целом идею уловил, и пару раз сам использовал stateful jwt (не зная о различиях), просто потому что сравнение его с тем, который хранится в БД – звучало в голове здраво, поэтому видимо пока правильно иду

Идентификатор сессии через куки для браузерных клиентов, для андроид и эпл jwt?

Не согласен, что claim означает одноразовый. Statefull подразумевает, что каждый сервис имеет доступ к state, чем бы он не был обеспечен, что не всегда так.

По сути проблема только одна - невозможность моментального отзыва токена. Вторя автору, а часто ли вам приходится отзывать их? То есть если у вас какое-то особенное приложение, где часто происходит изменение прав пользователя, то возможно вам нужно другое решение.

И напоследок, не все приложения/клиенты, которые пользуются API - web-страницы. И обслуживание cookies в них не происходит автоматически.

серьезно?

этого недостаточно чтобы отказаться от jwt.

jwt - это простое, обкатанное решение

даже при наличии всех этих "проблем", я хз что может быть лучшим stateless решением (особенно в паре с куками)

сессия, которую продвигает автор - уже не stateless

Автор пишет, что будет сравнивать plain text и jwt сессии, а потом постоянно вспоминает куки/localstorage.

Обычно никто не делает авторизацию «с нуля». По моим наблюдениям в библиотеках для авторизации jwt сессии используется по умолчанию и требуют меньше дополнительного кода, поэтому многие используют их в мелких проектах.

По сути главный недостаток jwt сессий в том, что их трудно инвалидировать извне. То есть при простейшей реализации jwt сессий (подписанный user id) если пользователя взломали, то даже если он сменит пароль у злоумышленника останется доступ к аккаунту. Самый простой способ решения этой проблемы - использовать plain text сессии, хранящиеся в бд.

Единственный правильный способ защититься от CSRF атак – это CSRF-токен

Ну да ну да, x-requested-with просто курит в сторонке. И в век реактов шлёпать обычные формы и рассуждать, что сайт не работает с выключенным js? Ну камон, хоть радует, что это перевод, и это где-то там интернет эксперты застряли в 19 веке

Как передавать "стандартную" сессию между сабдоменами? С jwt достаточно просто хранить рефреш в куках и аксесс в каком-нибудь localstorage. ТК авторизуемся мы именно по аксессу, за которым нужно ходить в /refresh, то CORS защитит нас от CSRF.

А вот в "стандартном" подходе нам необходим CSRF токен. И нам нужно как-то сделать, чтобы сабдомены о нем знали, а другие - нет. Простых и чистых вариантов не вижу.

Sign up to leave a comment.

Articles