Я хотел бы реализовать аутентификацию на основе JWT в нашем новом REST API. Но так как срок действия установлен в токене, возможно ли автоматически продлить его? Я не хочу, чтобы пользователям приходилось регистрироваться через каждые X минут, если они активно использовали приложение в этот период. Это было бы огромным провалом UX.
Но продление срока действия создает новый токен (и старый действует до тех пор, пока не истечет срок его действия). И генерирование нового токена после каждого запроса звучит для меня глупо. Похоже, проблема безопасности, когда более одного токена действительны одновременно. Конечно, я могу аннулировать старый использованный, используя черный список, но мне нужно будет хранить токены. И одним из преимуществ JWT является отсутствие хранилища.
Я нашел, как Auth0 решил это. Они используют не только токен JWT, но и токен обновления: https://docs.auth0.com/refresh-token
Но опять же, чтобы реализовать это (без Auth0), мне нужно хранить токены обновления и поддерживать их срок действия. Какова реальная выгода тогда? Почему бы не иметь только один токен (не JWT) и сохранить срок действия на сервере?
Есть ли другие варианты? Разве использование JWT не подходит для этого сценария?
Ответы:
Я работаю в Auth0 и участвовал в разработке функции обновления токенов.
Все зависит от типа приложения, и вот наш рекомендуемый подход.
Веб-приложения
Хорошим примером является обновление токена до его истечения.
Установите срок действия токена на одну неделю и обновляйте токен каждый раз, когда пользователь открывает веб-приложение, и каждый час. Если пользователь не открывает приложение более недели, ему придется снова войти в систему, и это приемлемый UX веб-приложения.
Для обновления токена вашему API требуется новая конечная точка, которая получает действительный, не истекший JWT и возвращает тот же подписанный JWT с новым полем срока действия. Тогда веб-приложение будет где-то хранить токен.
Мобильные / родные приложения
Большинство нативных приложений регистрируются один раз и только один раз.
Идея состоит в том, что токен обновления никогда не истекает, и его всегда можно обменять на действительный JWT.
Проблема с токеном, который никогда не истекает, состоит в том, что никогда не значит никогда. Что вы делаете, если вы потеряете свой телефон? Таким образом, пользователь должен каким-то образом идентифицировать его, а приложение должно предоставлять способ отзыва доступа. Мы решили использовать имя устройства, например, «maryo's iPad». Затем пользователь может зайти в приложение и отозвать доступ к «iPad от maryo».
Другой подход заключается в отзыве токена обновления для определенных событий. Интересным событием является смена пароля.
Мы считаем, что JWT бесполезен для этих случаев использования, поэтому мы используем случайно сгенерированную строку и храним ее на нашей стороне.
источник
В случае, если вы сами обрабатываете аутентификацию (т.е. не используете провайдера, такого как Auth0), может работать следующее:
Флаг 'reauth' в базе данных базы данных будет установлен, когда, например, пользователь сбросил свой пароль. Флаг удаляется, когда пользователь входит в следующий раз.
Кроме того, допустим, у вас есть политика, согласно которой пользователь должен входить в систему как минимум раз в 72 часа. В этом случае логика обновления токена API также проверит дату последнего входа пользователя в базу данных пользователя и запретит / разрешит обновление токена на этой основе.
источник
Я возился при переносе наших приложений на HTML5 с RESTful apis в бэкэнде. Решение, которое я придумал, было:
Как видите, это уменьшает частые запросы на обновление токенов. Если пользователь закрывает браузер / приложение до вызова возобновления токена, срок действия предыдущего токена истекает, и пользователю придется повторно войти в систему.
Более сложная стратегия может быть реализована для удовлетворения бездействия пользователя (например, пренебрежение открытой вкладкой браузера). В этом случае возобновление вызова токена должно включать ожидаемое время истечения, которое не должно превышать установленное время сеанса. Приложение должно будет отслеживать последнее взаимодействие с пользователем соответственно.
Мне не нравится идея установки длительного срока действия, поэтому этот подход может не работать с нативными приложениями, требующими менее частой аутентификации.
источник
Альтернативное решение для аннулирования JWT без какого-либо дополнительного безопасного хранилища на серверной стороне состоит в реализации нового
jwt_version
целочисленного столбца в таблице пользователей. Если пользователь желает выйти из системы или прекратить действие существующих токенов, они просто увеличиваютjwt_version
поле.При создании нового JWT закодируйте его
jwt_version
в полезную нагрузку JWT, дополнительно увеличивая значение заранее, если новый JWT должен заменить все остальные.При проверке JWT
jwt_version
поле сравнивается с полем,user_id
и авторизация предоставляется, только если оно совпадает.источник
Хороший вопрос - и в самом вопросе много информации.
Статья « Обновить токены: когда их использовать и как они взаимодействуют с JWT» дает хорошую идею для этого сценария. Некоторые моменты:
Также взгляните на auth0 / angular-jwt angularjs
Для веб-API. Прочитайте Включить маркеры обновления OAuth в приложении AngularJS с помощью ASP .NET Web API 2 и Owin
источник
Я фактически реализовал это в PHP, используя клиент Guzzle для создания клиентской библиотеки для API, но концепция должна работать для других платформ.
Обычно я выдаю два токена: короткий (5 минут) и длинный, срок действия которого истекает через неделю. Клиентская библиотека использует промежуточное программное обеспечение для попытки одного обновления короткого токена, если она получает ответ 401 на какой-либо запрос. Затем он снова попытается выполнить исходный запрос, и, если ему удалось обновить, он получит правильный ответ, прозрачно для пользователя. Если это не удалось, он просто отправит 401 пользователю.
Если срок действия короткого токена истек, но он все еще аутентичен, а длинный токен действителен и аутентичен, он обновит короткий токен с помощью специальной конечной точки в службе, которую аутентифицирует длинный токен (это единственное, для чего он может использоваться). Затем он использует короткий токен, чтобы получить новый длинный токен, тем самым продлевая его еще на одну неделю каждый раз, когда обновляет короткий токен.
Этот подход также позволяет нам аннулировать доступ в течение не более 5 минут, что является приемлемым для нашего использования без необходимости хранить черный список токенов.
Позднее редактирование: перечитывая эти месяцы после того, как это было свежо в моей голове, я должен отметить, что вы можете отменить доступ при обновлении короткого токена, потому что это дает возможность для более дорогих вызовов (например, вызов в базу данных, чтобы увидеть, если пользователь был забанен) без оплаты за каждый звонок к вашему сервису.
источник
Ниже приведены инструкции по отзыву вашего токена доступа JWT:
1) Когда вы входите в систему, отправьте 2 токена (токен доступа, токен обновления) в ответ клиенту.
2) У маркера доступа будет меньше время истечения, а у обновления будет долгое время истечения.
3) Клиент (Front end) будет хранить токен обновления в своем локальном хранилище и токен доступа в куки.
4) Клиент будет использовать токен доступа для вызова API. Но когда он истекает, выберите токен обновления из локального хранилища и вызовите сервер аутентификации api, чтобы получить новый токен.
5) На вашем сервере аутентификации будет открыт API, который примет токен обновления, проверит его действительность и вернет новый токен доступа.
6) Когда срок действия маркера обновления истечет, пользователь выйдет из системы.
Пожалуйста, дайте мне знать, если вам нужна дополнительная информация, я также могу поделиться кодом (загрузка Java + Spring).
источник
JWT-автообновление
Если вы используете узел (React / Redux / Universal JS), вы можете установить
npm i -S jwt-autorefresh
.Эта библиотека планирует обновление токенов JWT за определенное пользователем количество секунд до истечения срока действия токена доступа (на основе утверждения exp, закодированного в токене). Он имеет обширный набор тестов и проверяет множество условий, чтобы гарантировать, что любая странная деятельность сопровождается описательным сообщением о неправильной конфигурации из вашей среды.
Полный пример реализации
отказ от ответственности: я сопровождающий
источник
jwt-autorefresh
его декодирует, - это извлечениеexp
заявки, чтобы она могла определить, как далеко планировать следующее обновление.Я решил эту проблему, добавив переменную в данные токена:
Я установил
expiresIn
опцию на желаемое время, прежде чем пользователь будет вынужден снова войти в систему. Мой установлен на 30 минут. Это должно быть больше, чем значениеsoftexp
.Когда мое клиентское приложение отправляет запрос к API сервера (где требуется токен, например, страница списка клиентов), сервер проверяет, является ли отправленный токен по-прежнему действительным или нет, основываясь на его первоначальном
expiresIn
значении expiration ( ). Если это не верно, сервер ответит с определенным статусом для этой ошибки, например.INVALID_TOKEN
,Если токен все еще действителен на основе
expiredIn
значения, но он уже превысилsoftexp
значение, сервер ответит отдельным сообщением об этой ошибке, например.EXPIRED_TOKEN
:На стороне клиента, если он получил
EXPIRED_TOKEN
ответ, он должен автоматически обновить токен, отправив запрос на обновление на сервер. Это прозрачно для пользователя и автоматически заботится о клиентском приложении.Метод обновления на сервере должен проверить, является ли токен все еще действительным:
Сервер откажется обновлять токены, если произошел сбой вышеуказанного метода.
источник
Как насчет этого подхода:
В этом случае нам не требуется дополнительная конечная точка для обновления токена. Был бы признателен любой обратной связи.
источник
Сегодня многие люди выбирают для выполнения управления сеансами с JWTs , не зная о том, что они отказываются от ради предполагаемой простоты. Мой ответ подробно описывает 2-ю часть вопросов:
JWT способны поддерживать базовое управление сеансами с некоторыми ограничениями. Будучи токенами с самоописанием, они не требуют состояния на стороне сервера. Это делает их привлекательными. Например, если у службы нет уровня постоянства, ему не нужно вводить его только для управления сеансом.
Однако безгражданство также является основной причиной их недостатков. Поскольку они выдаются только один раз с фиксированным содержимым и сроком действия, вы не можете делать то, что хотели бы, с помощью обычной настройки управления сеансом.
А именно, вы не можете сделать их недействительными по требованию. Это означает, что вы не можете реализовать безопасный выход из системы, поскольку нет способа истечения срока действия уже выданных токенов. Вы также не можете реализовать время простоя по той же причине. Одним из решений является сохранение черного списка, но это вводит состояние.
Я написал пост, объясняющий эти недостатки более подробно. Чтобы было ясно, вы можете обойти это, добавив больше сложности (скользящие сеансы, обновления токенов и т. Д.)
Что касается других вариантов, если ваши клиенты взаимодействуют с вашим сервисом только через браузер, я настоятельно рекомендую использовать решение для управления сеансами на основе файлов cookie. Я также составил список методов проверки подлинности, которые в настоящее время широко используются в Интернете.
источник