Проблема одновременного обновления токена в Dart с ASP.NET Core WebAPI - PullRequest
0 голосов
/ 08 октября 2018

Я написал простое приложение во Флаттере, используя Dart.Я использую токены JWT для аутентификации пользователя.Первичный токен действителен только 60 секунд.Когда пользователь отправляет запрос с токеном с истекшим сроком действия, webapi возвращает 401. Затем в своем коде Dart я проверяю, является ли код состояния ответа 401. Если да, то я отправляю запрос конечной точке RefreshToken и отправляю запрос еще раз (этот запрос возвратил 401 ранее).

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

1 Ответ

0 голосов
/ 08 октября 2018

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

Я использую flutter-redux для управления состоянием на стороне клиента.

  1. Получите токен jwt после входа в систему
  2. Расшифруйте токен jwt на стороне клиента в ответ на запрос от сервера.
  3. Содержит тайм-аут - время истечения.
  4. Создание промежуточного промежуточного программного обеспечения на стороне клиента, скажем, _createRefreshTokenMiddleware.
  5. Каждый запрос от клиента должен проходить через это промежуточное программное обеспечение перед отправкой на сервер.
  6. В этом промежуточном программном обеспечении при каждом запросе к серверу проверяется время ожидания токена, если токен истек, удерживайте запрос, отправьте запрос на сервер, чтобы обновить токен, дождитесь получения нового токена, используйте этот новый токен, чтобы отправить запрос на сервер.
  7. Все остальные запросы, для которых истекает токен, будут ожидать обычного обещания.Допустим, скажем refreshTokenPromise, чтобы получить refreshToken будет решен в первую очередь.Таким образом, вам не нужно отправлять несколько запросов refreshToken.
  8. Если токен все еще действителен, разрешите выполнение запросов.

См. Приведенный ниже пример -

Ваше промежуточное ПО:

Middleware<AppState> _createRefreshTokenMiddleware() {
  return (Store store, action, NextDispatcher next) async {
    AppState appState = store.state;
    AuthState auth =  appState.auth;

    if (isTokenExpired(auth)) {
      if (auth.refreshTokenPromise == null) {
        refreshToken(store).then((res) => next(action));
      } else {
        auth.refreshTokenPromise.then((res) => next(action));
      }
    }
    next(action);
  };
}

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

Проверка истечения срока действия токена:

bool isTokenExpired(AuthState auth) {
  int bufferSeconds = 10;
  if(auth != null && auth.authTokens != null && auth.authTokens.tokenExpiryTime != null) {
    var currentTime = DateTime.now();
    Duration durationRemaining = auth.authTokens.tokenExpiryTime.difference(currentTime);

    return (durationRemaining.inSeconds - bufferSeconds) <= 0 ? true : false;

  }
  return false;
}

Вы отправляете запрос на обновление токена за 10 секунд до негосрок действия истек.

AuthState Модель:

@ неизменяемый класс AuthState {

// properties
final bool isAuthenticated;
final bool isAuthenticating;
final AuthTokens authTokens;
final String error;
final Future<dynamic> refreshTokenPromise;

// constructor with default
AuthState({
    this.isAuthenticated = false,
    this.isAuthenticating = false,
    this.authTokens,
    this.error,
    this.refreshTokenPromise,
});

}

Ваше состояние авторизациимодель может быть такой же, как и выше.

AuthToken:

@immutable
class AuthTokens {

  // properties
  final String accessToken;
  final String refreshToken;
  final DateTime tokenExpiryTime;

  // constructor with default
  AuthTokens({
    this.accessToken,
    this.refreshToken,
    this.tokenExpiryTime,
  });
 }

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...