Подтвердить что ты не робот

Рекомендации по недействительности JWT при изменении паролей и выхода из системы в node.js?

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

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

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

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

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

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

4b9b3361

Ответ 1

Если используется токен Refresh Refresh:

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

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

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

  • Проверьте, действителен ли токен.
  • Если он действителен, проверьте, присутствует ли он в invalidTokenDB (база данных, где выгруженные токены хранятся до истечения срока их действия).
  • Если его нет, проверьте время создания маркера и измените время пароля в пользовательском db.
  • Если измененное время пароля < токен создан, тогда токен действителен.

Обеспокоенность описанным выше способом:

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

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

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

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

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

  • проверить, действительно ли токен или нет.
  • Если это действительно так, проверьте, присутствует ли токен в InvalidTokenDB.
  • Если нет, проверьте токен обновления с токеном обновления в userDB.
  • Если equals, то его действительный токен

Обеспокоенность описанным выше способом:

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

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

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

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

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

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

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

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

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

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

Ответ 2

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

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

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

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

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

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

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

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

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

Ответ 3

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

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

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

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

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

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

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

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

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

Примечание. Пожалуйста, объясните, если вы голосуете.

Ответ 4

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

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

Ответ 5

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