Я сразу перейду к вопросу о том, как реализовать токен обновления для ASP.NET (Core), поэтому в этой истории предполагается, что вы уже реализовали токены JWT. Об этом много статей 😄

Что такое токены обновления?

Вкратце, вы можете думать о токенах обновления как о:

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

Так как же его реализовать?

Обратите внимание, что перед этим необходимо внести следующие изменения в существующую конечную точку входа (для меня она находится под /api/Auth/login):

  1. Измените объект возврата в конечной точке входа в систему так, чтобы вы возвращали следующее:
{
  "accessToken": "<JWT Token>",
  "accessTokenExpiration": "<A value that tells up to when is the access token valid."
  "refreshToken": "<Refresh Token>"
}
  • «AccessToken» - это в основном ваш токен JWT.
  • «AccessTokenExpiration» - необязательно. Но это представляет собой значение, которое сообщает вашему клиенту, когда токен доступа действителен. Вам решать, хотите ли вы вернуть число в два раза, чтобы указать минуты. Обычно для этого я использую DateTimeOffset.
  • «RefreshToken» - здесь вы разместите токен обновления, который клиент может использовать для получения нового токена JWT.

2. Измените способ создания токена JWT, убедившись, что идентификатор пользователя включен в ваш токен JWT через утверждения, через или тему:

Обратите внимание, что вам нужно добавить Заявление, которое можно использовать для простой идентификации пользователя на основе токена JWT. Я обычно использую для этого Заявление ClaimTypes.Name.

3. В рабочем процессе входа в систему убедитесь, что «Обновить поток токенов во время входа в систему» ​​и «Использование токена обновления» (см. Ниже).

Обновить поток токенов во время входа в систему

Этот поток может быть размещен до или после генерации токена JWT.

  1. Сгенерируйте случайный токен:

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

Вы можете использовать свою собственную реализацию для генерации случайного значения, но, например, выше я использовал System.Security.Cryptography.RandomNumberGenerator.

Некоторые предлагают использовать для этого GUID, но другие говорят, что у GUID есть шаблон. В конце концов, вам решать, что использовать.

2. Сохраните токен обновления вместе с истечением срока его действия в своей базе данных / репозитории.

Это очень важный шаг. Помните, что наши токены обновления действительно случайны, и их действительно сложно угадать?

Что ж, мы должны найти способ проверить, действителен ли предоставленный нам токен обновления или нет. Так как же нам это сделать? Храните жетоны обновления где-нибудь.

Вот обзор всего потока:

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

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

Использование токена обновления

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

  1. Создайте новую конечную точку, которая позволяет AnonymousAccess:

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

Ответ аналогичен тому, который возвращает конечная точка входа в систему.

2. Получите идентификатор пользователя из токена JWT (это также сообщит нам, действителен ли токен JWT).

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

4. Убедившись, что токен обновления действителен, вы можете сгенерировать новый токен JWT с новым сроком действия и новым токеном обновления и вернуть их клиенту. 😄

На что следует обратить внимание:

  • При использовании токенов обновления лучше всего удалить их из базы данных, чтобы их нельзя было использовать снова. Я обычно удаляю их сразу после использования токена обновления.
  • Бывают случаи, когда токены обновления не используются и срок их действия уже истек. У меня есть HostedService, который периодически запускается, чтобы их очистить.
  • Если вы хотите, чтобы ваш пользователь был активен только на одном устройстве, нет необходимости хранить несколько токенов обновления в вашем репозитории.