Comments 21
Если у вас API требует access_token, то это не "удобно" или "не удобно", это единственный вариант.
Или получать его из сервиса аутентикации при каждой загрузке страницы и хранить в памяти. В принципе, это более широкая трактовка того, что в статье названо "хранение токенов обновления в HttpOnly-куки, а токенов доступа — в памяти"
Наверное, имеются ввиду Secure флаг
Именно так. В оригинале secure
выделено как ключевое слово, наравне с httpOnly
. Переводчик не осилил.
Но secure флаг никак не защищает куки от доступа к ним с помощью JS.
А тут уже претензия не к переводу, а к автору оригинала. Зачем он приплел сюда secure — непонятно.
пользователя каким-то образом принуждают
Очередная кривая формулировка автора оригинала. Кто в курсе, тот поймет (но ему это объяснение и не нужно), а кто не курсе, того такое описание только запутает.
Это какие такие защищенные куки? Наверное, имеются ввиду Secure флаг, который запрещает передачу куков при http запросе. Но secure флаг никак не защищает куки от доступа к ним с помощью JS.
Полагаю, имеется в виду как раз флаг HttpOnly.
«А зачем нужен JWT если раньше обходились session id / токен?»
И если кратко то JWT, это шифрованный user profile, который передают через клиента, и нужен он для:
(а) кластеризации за лоад-балансером, и (б) авторизации, без обращения к база/сервису на каждый запрос пользователя.
Статья не то чтобы не раскрывает тему, она больше вводит в заблуждение...
Существуют сценарии, при реализации которых вы не можете передавать куки своему API-серверу.
А потом складываем refresh token в куки… выходит от недостатка не избавились...
Из моего опыта хранить токены нужно только в оперативной памяти и отправлять в хедерах.
Для меня тоже долгое время было большой загадкой, а где таки хранить токены. После некоторого погружения в бекенд моя картина мира складывается в вариант, когда мы выносим сервис авторизации в отдельный сервис (на отдельном домене), с которым у нас есть нормальная куки сессия, хранящаяся на бекенде в базе и т.д. и т.п., от этого сервиса мы получаем токены, храним их в оперативной памяти и уже с ними ходим в остальные сервисы.
Причем нигде не должно быть возни с CORS, клиент всегда шлет на родной домен запросы, которые проверяются одним api gateway'ем, а потом раскидываются по сервисам.
Еще одной замечательной особенностью токенов является их независимость от браузерных особенностей работы с куками, что позволяет использовать их между серверами и с мобильных устройств, что также упущено в этой статье.
Я верю, что мой коммент будет полезен тем, кто начинает читать статьи с комментариев =)
В описанном мной примере хранить не нужно, так как мы можем сходить к серверу авторизации за новыми токенами при перезагрузки страницы. Для того, чтобы это сделать нам нужна сессия на сервере авторизации, это скорее всего будет что-то в httpOnly куках, но это не будут те же токены, которые мы будем использовать на других сервисах.
Мне на самом деле интересны проблемы, которые тут можно огрести, и которые я пока не вижу,… но я их пока не вижу =)
Я просто пришел к аналогичному выводу, и вы его подтвердили. Совершенно непонятно, какой смысл хранить оба токена в одной куке, и, получается передавать их с запросами. Смысл рефреша теряется, он все равно ходит парой с токеном доступа. Важным аспектом то было то, чтобы отправлять рефреш только когда нужен рефреш… В общем, идея с отдельным доменом эту проблему как раз и решает. Отнимаем доступ у приложения к кукам с помощью httponly и получаем отдельно куку для доступа и отдельно куку для рефреша.
ктонибудь организовывал через токены доступ к видео? чтобы их с помощью софта не скачивали
Размер куки-файлов ограничен 4 Кб. Поэтому, если вы используете большие JWT, хранение их в куки-файлах вам не подойдёт.
Сейчас бы отправлять 4кб в каждом запросе.
Локальное хранилище уязвимо к XSS-атакам
Почему всегда доступ из js в localStorage объявляют как минус? Ведь если на сайт УЖЕ прошла xss атака, т.е внедрили чужой js… то уже как бы поздно. Какая уже разница где хранятся токены. Наворотить уже можно что угодно по идее.
Т.е. в контексте вопроса в статье, переживать необходимо про xss, а не о том где бы безопаснее токены хранить.
Про это и упомянули:
при такой схеме работы злоумышленнику может быть выгоднее атаковать сервер, пользуясь компьютером жертвы, а не собственным.
Действительно, если ты нашел XSS, то тебя ничего не остановит.
Если куки прочитать нельзя (выставив флаг HttpOnly), то зачем их сравнивать?
Содержимое статьи можно уложить в три предложения — храним сессию в куках с флагами secure, HttpOnly и SameSite. Выставляем заголовки X-Content-Type-Options, Strict-Transport-Security, X-XSS-Protection, X-Frame-Options, Referrer-Policy, Content-Security-Policy, Expect-CT, Feature-Policy и Cache-Control. Ну и не забываем про токен.
Так то refresh token’ы нельзя выдавать в браузер. В случае использования OpenID Connect была возможность так называемого «silent renew», но судя по блогу разработчиков вебкита, она уже канула в лету (для Safari — в последних Technology Preview, для Chrome — в 2022) https://webkit.org/blog/10218/full-third-party-cookie-blocking-and-more/
В драфтах OAuth 2.1 implicit flow выпилили, остались только только authorization code с pkce для public/confidential клиентов и client credentials flow. Соответственно единственный вариант для больших SPA, которые разрабатываются сейчас, с заделом на долгую и счастливую поддержку, которым от провайдера нужно чуть побольше, чем просто аутентификация — это code + pkce и httponly secure куки, к которым имеет доступ только BFF.
https://gist.github.com/zmts/802dc9c3510d79fd40f9dc38a12bccfc
Локальное хранилище или куки? Безопасное хранение JWT на клиенте