asp.net - 使用 ASP.NET Core WebAPI 的 Dart 中的 token 刷新并发问题

标签 asp.net asp.net-core dart flutter jwt

我使用 Dart 在 Flutter 中编写了一个简单的应用程序。我使用 JWT token 对用户进行身份验证。主 token 仅在 60 秒内有效。 当用户发送带有过期 token 的请求时,webapi 返回 401。 然后在我的 Dart 代码中检查响应的状态码是否为 401 如果是,那么我向 RefreshToken 端点发送请求并再次发送请求(此请求之前返回 401)。

如果用户做很多 Action 太快,过期的 token 会被更新很多次。 我想避免这种情况。 在完美的灵魂中,当 token 正在刷新时,其他请求应该等待。

最佳答案

我遇到了类似的问题,并尝试使用以下方法解决它。

我使用 flutter-redux 来管理客户端的状态。

  1. 登录后获取jwt token
  2. 根据服务器的响应在客户端解码 jwt token 。
  3. 它包含超时 - 到期时间。
  4. 在客户端创建一个 redux 中间件,比如 _createRefreshTokenMiddleware
  5. 来自客户端的每个请求在发送到服务器之前都应该经过这个中间件。
  6. 在这个中间件中,每次向服务器请求时,检查 token 超时,如果 token 过期,保留这些请求,向服务器发送请求以刷新 token ,等待直到收到新 token ,使用这个新 token 发送那些向服务器请求。
  7. token 将过期的所有其他请求将等待一个共同的 promise ,让我们说 refreshTokenPromise 以首先解决 refreshToken。这样您就不必发送多个 refreshToken 请求。
  8. 如果 token 仍然有效,则让请求通过。

引用下面的例子-

您的中间件:

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);
  };
}

token 过期的所有请求都将等待 refreshTokenPromise 得到解决,一旦解决,所有待处理的请求都会在请求 header 中设置新的更新 token (例如)。

检查 token 是否过期:

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;
}

您在 token 实际过期前 10 秒发送刷新 token 的请求。

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,
});

您的授权状态模型可以像上面那样。

授权 token :

@immutable
class AuthTokens {

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

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

虽然我在这里给出了基于 redux 的解决方案,但同样的策略也可以应用于其他任何地方。希望对您有所帮助。

关于asp.net - 使用 ASP.NET Core WebAPI 的 Dart 中的 token 刷新并发问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52696026/

相关文章:

c# - 在单个查询中使用多个 DataContext 的 Linq to SQL

c# - 在 asp.net 中使用 croppic

c# - .net Core 2.1 中缺少 System.Web.Http

configuration - 在 MVC 6 中访问依赖注入(inject)服务

flutter - 有没有一种方法可以按字符串中的数字对字符串列表进行排序?

asp.net - Visual Studio : Convert 'Empty ASP.NET' template into MVC

asp.net - HTMLEditorExtender 在异步回发时对 img 标签进行编码

c# - 在 ASP.NET Core 2.0 中传递 JSON 对象作为 JWT token 的声明

dart - dart vm有效,但dart2js失败

android - 如何检查按钮是否被按下