JWT и одноразовые токены?

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

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

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

Любые идеи?


person Inx51    schedule 01.05.2017    source источник
comment
Зачем вам это нужно, чтобы это было только один раз? Что произойдет, если токен будет использован во второй раз?   -  person Constantin Galbenu    schedule 01.05.2017
comment
Я думаю, что если мы сгенерируем только один токен, который будет использоваться для всех конечных точек... и скажем, у нас есть конечная точка для удаления записей в базе данных... тогда человек посередине или просто кто-то, кому удастся завладеть этим токеном ОДИН РАЗ сможет создать несколько запросов на удаление и нанести большой ущерб ... однако ... если токен можно использовать только один раз, то ущерб будет, по крайней мере, ограниченным ... Хотя я могу ошибаться ...   -  person Inx51    schedule 01.05.2017
comment
Решения существуют, но они зависят от вашего бизнеса.   -  person Constantin Galbenu    schedule 01.05.2017
comment
Ваше обоснование не верно. Даже если вы сделаете недействительными после первого использования, этот посредник может поймать еще один и еще токен и так далее.   -  person Constantin Galbenu    schedule 01.05.2017
comment
Верно.. но использование одного токена для проверки всей аутентификации, я думаю, значительно облегчило бы задачу человеку посередине.. скажем, мы можем попытаться завладеть токеном.. срок действия токена истекает через 30 минут после его создания. ... это оставит наши конечные точки API незащищенными в течение 30 минут ... однако ... если мы аннулируем уже использованный токен и предоставим новый токен ... тогда, возможно (только может быть), наш фактический пользователь мог уже использовать этот токен, и он было бы бесполезно для нашего человека посередине.. конечно, это небезопасно.. но это все еще один дополнительный уровень безопасности.. я думаю?   -  person Inx51    schedule 01.05.2017
comment
Я не согласен. Вы слишком усложняете вещи и почти ничего не получаете. Однако, если вам все еще нужны эти одноразовые токены, посмотрите мой ответ.   -  person Constantin Galbenu    schedule 01.05.2017
comment
Хорошо, да .. большое спасибо за ваш отзыв :)!   -  person Inx51    schedule 01.05.2017


Ответы (4)


Используйте хэш текущего пароля пользователя для подписи токена JWT, таким образом, все токены, сгенерированные до успешного изменения пароля, в следующий раз станут недействительными. Я взял идею отсюда https://www.jbspeakr.cc/howto-single-use-jwt/.

person Dhruv Parmar    schedule 12.11.2018

Решения, конечно, есть.

Как и в любой распределенной системе (вы упомянули масштабируемость), вам приходится выбирать между доступностью и стабильностью.

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

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

Какое решение подходит лучше всего, зависит от вашего бизнеса.

person Constantin Galbenu    schedule 01.05.2017
comment
Да, на данный момент идея состоит в том, чтобы хранить токены в кеше Redis. Однако я не уверен, сколько накладных расходов на производительность это добавит ... поэтому, если бы можно было избежать использования базы данных, это было бы приятно ... однако, я думаю, это может быть сложно ... или невозможно: / Я также мог бы чрезмерно усложняя это, поскольку снижение производительности может быть даже незаметным ... но я подумал, что все возможные решения должны быть исследованы, прежде чем я приму решение ... - person Inx51; 01.05.2017

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

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

На самом деле есть некоторые БД, у которых есть TTL для записей (dynamoDB, mongodb), поэтому вы просто поместите токены и установите TTL на момент истечения срока действия токена.

person Mrk Fldig    schedule 01.05.2017
comment
Ах, хорошо, да, я кое-что читал о занесении в черный список уже использованных токенов... это может быть одним из способов сделать это... однако... и я знаю, что это почти невозможно... но можно ли использовать одноразовые токены без потребность в БД (любой...).. для обработки токена как лица без гражданства? - person Inx51; 01.05.2017
comment
Я лично не могу придумать другого способа, почему пытаются избежать БД? Вы могли бы просто использовать redis/TTL, чтобы БД не стала такой большой, если бы вы установили короткое время истечения срока действия токенов? - person Mrk Fldig; 01.05.2017
comment
Нужно иметь какое-то состояние транзакции, т.е. использовалось что-то вроде токена ABC. Если вы хотите, чтобы он был легче, вы можете использовать nonce в jwt и сохранить это состояние против этого nonce в db, поэтому вам не нужно хранить весь токен. В любом случае вы должны использовать либо ttl, либо пакетное задание для удаления устаревших данных из базы данных, если вас беспокоит размер базы данных. - person AD.Net; 01.05.2017

Как уже упоминалось, это зависит от вашего бизнес-кейса. Ссылки для сброса пароля могут быть указаны на https://www.jbspeakr.cc/howto-single-use-jwt/.

Если у вас есть сценарий Single-Use & Single-Auth, в котором вы можете захотеть аннулировать любой ранее использованный и неиспользованный токен, вы можете сохранить один одноразовый номер и обновлять его при каждом запросе нового токена, а также при его использовании.

person Carlos P.    schedule 30.01.2019