Рекомендации по аннулированию JWT при изменении паролей и выходе из системы в узле.Джей? [закрытый]


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

У меня есть идея ниже, чтобы обрабатывать выше 2 случаев, нажав на базу данных пользователей.

1.В случае изменения пароля я проверяю пароль (хэш), хранящийся в пользовательской БД.

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

но эти 2 случая происходят за счет удара пользователя db каждый раз, когда пользователь попадает в api. Любая лучшая практика ценится.

обновление: Я не думаю, что мы можем сделать недействительным JWT, не нажимая db. Поэтому я придумал решение. Я опубликовал свой ответ, если у вас есть какие-либо проблемы, добро пожаловать.

5 51

5 ответов:

если токен обновления не используется:

1.При смене пароля: когда пользователь меняет свой пароль, обратите внимание на время изменения пароля в БД пользователя, поэтому, когда время изменения пароля больше времени создания токена, Токен недействителен. Следовательно, оставшаяся сессия скоро выйдет из системы.

2.Когда пользователь выходит из системы: когда пользователь выходит из системы, сохраните маркер в отдельной БД (скажем: InvalidTokenDB и удалите токен из БД, когда токен истекает). Следовательно, пользователь выходит из соответствующего устройства, его сеансы в другом устройстве остаются нетронутыми.

следовательно, при аннулировании JWT я выполняю следующие шаги:

  1. проверьте, является ли токен действительным или нет.
  2. если он действителен, проверьте его наличие в invalidTokenDB (база данных, в которой маркеры выхода из системы хранятся до истечения срока их действия).
  3. если его нет, то проверьте время создания и изменения токена пароль пользователя БД.
  4. если изменено время пароля

беспокойство с вышеуказанным методом:

  1. для каждого запроса api мне нужно выполнить все вышеперечисленные шаги, которые могут повлиять на производительность.

когда используется токен обновления: с истечением срока действия маркера доступа как 1 день, обновить маркер как срок действия

1. При изменении пароль: когда пользователь меняет свой пароль, измените токен обновления пользователя. Следовательно, оставшаяся сессия скоро выйдет из системы.

2. Когда пользователь выходит из системы: когда пользователь выходит из системы, сохраните токен в отдельной БД (скажем: InvalidTokenDB и удалите токен из БД по истечении срока действия токена). Следовательно, пользователь выходит из соответствующего устройства, его сеансы в другом устройстве остаются нетронутыми.

следовательно, при признании недействительным JWT, я следую ниже шаги:

  1. проверьте, является ли токен действительным или нет
  2. если это допустимо, проверьте, присутствует ли токен в InvalidTokenDB.
  3. если нет, проверьте токен обновления с помощью токена обновления в userDB.
  4. Если равно, то его действительный токен

беспокойство с вышеуказанным методом:

  1. для каждого запроса api мне нужно выполнить все вышеперечисленные шаги, которые могут повлиять спектакль.
  2. как я могу аннулировать токен обновления, поскольку токен обновления не имеет действительности, если его использует хакер, все равно аутентификация действительна, запрос всегда будет успешным.

Примечание: хотя Ханц предложил способ защитить токен обновления в использование токена Refesh в аутентификации на основе токенов защищено?, я не мог понять, что он говорит. Любая помощь приветствуется.

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

обновление: Я добавляю ответ, если ваше приложение не нуждается в маркере обновления с истекшим сроком службы. Этот ответ был дан Sudhanshu (https://stackoverflow.com/users/4062630/sudhanshu-gaur). Спасибо Sudhanshu. Поэтому я считаю, что это лучший способ сделать это,

когда токен обновления не требуется и срок действия токенов доступа не истекает:

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

следовательно, при аннулировании JWT выполните следующие действия,

  1. получить информацию о пользователе и проверить, находится ли маркер в его базе данных пользователей. Если так позволяют.
  2. когда пользователь выходит из системы, удалите только этот маркер из его базы данных пользователей.
  3. когда пользователь меняет свой пароль, удалите все маркеры из своей базы данных пользователей и попросите его снова войти в систему.

Так что с этим подходом, вы не нужно хранить ни токены выхода из системы в базе данных до истечения срока их действия, ни хранить время создания токена при смене пароля, что было необходимо в вышеуказанных случаях. Однако я считаю, что этот подход действует только в том случае, если ваше приложение имеет требования без необходимости обновления маркера и без истечения срока действия маркеров.

Если кто-то имеет отношение к этому подходу, пожалуйста, дайте мне знать. Ваши комментарии приветствуются :)

Я не знаю способа произвольно аннулировать токен без участия базы данных так или иначе.

будьте осторожны с подхода 2 Если ваш сервис может быть доступен на нескольких устройствах. Рассмотрим следующий сценарий...

  • пользователь входит в систему с iPad, токен 1 выдается и хранится.
  • пользователь входит на сайт. Маркер 2 выдается. Пользователь выходит из системы.
  • пользователь пытается использовать iPad, маркер 1 был выпущен до выхода пользователя из системы с веб-сайта токен 1 теперь считается недействительным.

вы можете посмотреть на идею обновления хотя они требуют хранения базы данных тоже.

см. Также здесь для хорошего обсуждения SO относительно аналогичной проблемы, конкретного решения IanB, которое сохранит некоторые вызовы db.

предлагаемое решение Лично я бы подошел к этому именно так...пользователь аутентифицируется, выдается с доступом токен с коротким сроком действия (скажем, 15 минут) и токен обновления действителен либо в течение гораздо более длительного периода, либо на неопределенный срок. Сохраните запись этого токена обновления в БД.

всякий раз, когда пользователь "активен", выдайте новый токен аутентификации каждый раз (действительный в течение 15 минут каждый раз). Если пользователь не активен более 15 минут, а затем делает запрос (поэтому использует истекший jwt), проверьте правильность маркера обновления. Если он действителен (включая проверку БД), то выдайте новый токен аутентификации.

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

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

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

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

всякий раз, когда создается jwt, т. е. во время входа в систему или изменения/сброса пароля, вставьте jwt с идентификатором пользователя в таблицу и сохраните jti (номер uuid в основном) для каждого jwt. Тот же jti также входит в полезную нагрузку jwt. Эффективно СТИ однозначно определяет вышлю. Пользователь может иметь несколько jwts одновременно, когда учетная запись доступна с нескольких устройств или браузеров, и в этом случае jti дифференцирует устройство или пользовательский агент.

таким образом, схема таблицы будет, jti / userId. (и первичный ключ, конечно)

для каждого api проверьте, находится ли jti в таблице, что означает, что jwt является допустимым.

когда пользователь изменяет или сбрасывает пароль, удалите все jti этого идентификатора пользователя из БД. Создайте и вставьте новый jwt с новым jti в таблицу. Это приведет к аннулированию всех сеансов со всех других устройств и браузеров, кроме того, который изменил или сбросил пароль.

когда пользователь выходит из системы, удалите этот конкретный jti этого пользователя, но не все. Там будет один вход, но не один выход из системы. Поэтому, когда пользователь выходит из системы, он не должен выйти из всех устройств. Тем не менее, удаление всех jtis бы выйти из всех устройств.

Так что это будет одна таблица и никаких сравнений дат. Также это будет тот же случай, если используется токен обновления или нет.

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

Примечание: пожалуйста, рассуждайте, если вы не голосуете за него.

Если пользователь меняет свой пароль, вы попадете в БД там. Но не хотите попасть в БД для авторизации?

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

Я согласен исключительно с ответом @gopinath просто хочу добавить одну вещь, которую вы также должны удалить время смены пароля, когда все ваши токены истекли, например, предположим, что вы установили 3-дневное время истечения срока действия для каждого токена, чтобы истечь сейчас вместо того, чтобы просто нормально сохранять время смены пароля в базе данных вы также можете установить его время истечения 3 дней, потому что, очевидно, токены до этого будут истекать, поэтому не нужно проверять каждый токен снова, что время пароля или нет