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

Управление сроком действия/ "помнить меня" с JWT

Концептуально мне очень нравится JWT, поскольку он соответствует безгражданству REST и т.д. (без сохранения состояния на стороне сервера, все релевантные данные содержатся в токене).

О чем я не уверен: как бы вы справились с истечением токена, когда не подключены (т.е. функциональность "помнить меня" )?

В Интернете появилось освещение JWT, но я не мог найти никого, кто бы ответил на вопрос об истечении срока.

Уточнение: Я не спрашиваю, как обращаться с токеном в ближайшее время, но что делать, когда токен уже истек (пользователь закрыл сайт/приложение на некоторое время). Самое простое решение, которое приходит мне на ум, - это кеширование учетных данных пользователя, что довольно небезопасно.

4b9b3361

Ответ 1

Я не уверен, буду ли я следовать, но напишу, что я думаю.

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

Что делать, когда токен уже истек? Ничего.

Представьте, что я плачу за эти 5 дней и за меня, у меня была настоятельная необходимость, и я возвращаюсь домой (с картой в кармане). В отеле все равно, когда проходят 5 дней, карта - это просто бесполезный кусок пластика, и если вы попытаетесь использовать его в отеле, он ничего не сделает.

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

Если он войдет в систему, он получит токен в течение 7 дней, если он больше не будет его использовать, и через 20 дней он снова зайдет, ему нужно будет снова войти в систему, сервер просто отклонит ваши петиции, пока вы это сделаете.

Что бы я сделал, если вы используете что-то вроде angular в интерфейсе, это проверить правильность проверки маркера при запуске, чтобы вы могли иметь приятный пользовательский интерфейс.

То, что я не понимаю о вашем вопросе, - это кеширование.

Ответ 2

Вам нужно удержать JWT на клиенте, чтобы его доступная на странице загрузка, наиболее безопасная стратегия - это cookie только для HTTPS. Это отправит JWT на ваш сервер по каждому запросу, и сервер может проверить правильность токена и отклонить его, если он истек. Как вы справляетесь с истечением срока действия, зависит от типа используемого веб-приложения.

Для одностраничного приложения (например, Angular.js apps) вы захотите структурировать приложение, чтобы оно делало первоначальный запрос сервера до того, как он загрузит остальную часть приложения. Если сервер видит, что JWT в этом запросе истек, он выдаст ответ 401. Ваше приложение ответит на этот ответ, предоставив форму входа. В противном случае это будет продолжаться с предположением, что JWT действителен и может быть использован для доступа к требуемым ресурсам. Если в любое время приложение увидит 401, оно должно вернуть пользователя в форму входа.

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

Ответ 3

Я думаю, что вы спрашиваете, как недействить сторону сервера JWT для длинных токенов истечения срока действия (например, "помнить меня" )?

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

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

Ответ 4

Я могу думать об одном способе, но на самом деле он не определен.

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

{
    "iat": /* current time */,
    "bbf": /* current time + 1 hour -- expired means no resource access */
    "exp": /* current time + 1 week -- expired means cannot refresh */
}

(Примечание: я использую bbf для более короткой даты истечения срока действия. Нет конкретной причины, просто потому, что она имеет 3 символа в длину.)

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

И, наконец, когда "помнить меня" не проверено, просто используйте ту же жизнь для bbf и exp.

Ответ 5

В дополнение к @Jesus answer вы можете подумать о внедрении системы токенов обновления: https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/

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

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

Пример:

  • первый правильный вход для клиента: создать токен обновления, который действителен навсегда (пока он не будет удален или недействителен)
  • сохранить токен обновления в базе данных
  • токен доступа (JWT) с истечением срока действия для клиента (этот токен не сохраняется в базе данных)
  • для следующего запроса клиент отправляет токен доступа

  • Теперь проверьте, истек ли токен доступа:

    5.1 Ток доступа не истек, все в порядке

    5.2 Истек токен доступа, проверьте, есть ли токен обновления в базе данных

    5.2.1 Обновить токен в базе данных, вернуть новый токен доступа

    5.2.2 Нет Обновить токен в базе данных, вернуть 401/logout, Пользователь должен снова войти в систему

Надеюсь, что это поможет.