为什么我的JWT令牌字符串格式仅对某些HTTP请求变为无效?

问题描述

问题

我的JWT令牌字符串仅对某些请求变为无效。 JWT令牌字符串大约占我请求的90%,并且在发送HTTP请求时具有有效格式。但是对于某些请求,JWT令牌字符串变得混乱和/或引发FormatException。对于完全相同的请求会发生这种情况,这甚至更奇怪,这是用于从API提取项目的HTTP GET。

引发异常消息

异常类型:FormatException

消息:“无效的HTTP标头字段值:“ bearer nHkXXLympuU \ u0005 \ u0005 \ u0005 \ u0005 \ u0005 \u0014��cC\\ u0013D`--柳叶qNiIsInR5cCI6IkpXVCJ9.e…”

偏移:18

资料来源:“轴承nHkXXLympuUccC D'-柳�qNiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZjE3MWQwNy00NjMyLTRlOTUtODQ4NS05YjUwMWM1NjUUM2MTVzbGF>

hashCode:561613912

代码

调用http服务的方法

Future loadProjects() async {
    try {
      setShowLoadingOverlay(true,"Loading projects...");
      var response = await projectHttpService.getProjects(globals.companyId);
      setShowLoadingOverlay(false,"");
      if (HttpHelper.isSuccess(response))
        onLoadProjectsSuccess(response.body);
      else
        onLoadProjectsError();
    } catch (e) {
      setShowLoadingOverlay(false,"");
      onLoadProjectsError();
    }

Http服务准备使用JWT令牌发送的请求:

Future<http.Response> getProjects(String companyId) async {
    var url = globals.appApiBaseUrl +
        "Project?CompanyId=" +
        companyId +
        "&Status=" +
        Status.Todo.index.toString() +
        "&Status=" +
        Status.InProgress.index.toString();
    var refreshToken = await _secureStorageHelper.get("RefreshToken");
    var appToken = await _secureStorageHelper.get("ApplicationAccesstoken");

    return _jwtHandler.checkHandleExpiredJwt(
        url,null,appToken,refreshToken,HttpMessageType.Get);
  }

JWT帮助程序类发送请求,并确保令牌过期后刷新:

class HttpJwtHandler {
  IdentityHttpService _identityHttpService;
  SecureStorageHelper _secureStorageHelper;

  HttpJwtHandler() {
    _secureStorageHelper = new SecureStorageHelper();
    _identityHttpService = new IdentityHttpService();
  }

  Future<Response> checkHandleExpiredJwt(String url,dynamic body,String appToken,String refreshToken,HttpMessageType messageType) async {
    var validTokens = new Tuple2<String,String>(refreshToken,appToken);
    if (isTokenExpired(appToken)) {
      validTokens = await refreshTokens(refreshToken,appToken);
    }

    return send(url,body,validTokens.item2,validTokens.item1,messageType);
  }

  Future<Response> send(String url,HttpMessageType messageType) async {
    switch (messageType) {
      case HttpMessageType.Get:
        return sendGet(url,appToken);
      case HttpMessageType.Post:
        return sendPost(url,appToken);
      case HttpMessageType.Delete:
        return sendDelete(url,appToken);
      case HttpMessageType.Put:
        return sendPut(url,appToken);
      case HttpMessageType.Patch:
        return sendPatch(url,appToken);
      default:
        return null;
    }
  }

  bool isTokenExpired(String token) {
    var expiredDate = JWTHelper.getExpired(token);
    return expiredDate.compareto(DateTime.Now()) < 0;
  }

  Future<Tuple2<String,String>> refreshTokens(String refreshToken,String appToken) async {
    var refreshRequest = new RefreshTokenRequestModel(token: appToken,refreshToken: refreshToken);
    var response = await _identityHttpService.refreshTokens(refreshRequest);
    if (HttpHelper.isSuccess(response)) {
      // debugPrint("Refresh tokens: SUCCESS");
      // print("Refresh tokens: SUCCESS");
      var tokensTuple = extractTokens(response.body);
      await _secureStorageHelper.set("RefreshToken",tokensTuple.item1);
      await _secureStorageHelper.set("ApplicationAccesstoken",tokensTuple.item2);
      return tokensTuple;
    } else {
      // debugPrint("Refresh tokens: FAILURE");
      // print("Refresh tokens: FAILURE");
      var latestRefreshToken = await _secureStorageHelper.get("RefreshToken");
      var latestAppToken = await _secureStorageHelper.get("ApplicationAccesstoken");
      return new Tuple2(latestRefreshToken,latestAppToken);
    }
  }

  Tuple2<String,String> extractTokens(String body) {
    Map<String,dynamic> jsonMap = jsonDecode(body);
    return new Tuple2(jsonMap["refreshToken"],jsonMap["token"]);
  }

  Future<Response> sendGet(String url,String appToken) async {
    var response = http.get(url,headers: buildHeaders(appToken));
    return response.then<http.Response>((response) async {
      if (HttpHelper.isSuccess(response))
        return response;
      else {
        var validTokens = refreshTokens(refreshToken,appToken);
        return validTokens.then<http.Response>((validTokens) {
          return http.get(url,headers: buildHeaders(validTokens.item2));
        });
      }
    });
  }

  Future<http.Response> sendPost(
      String url,String appToken) async {
    var response = http.post(url,body: body,appToken);
        return validTokens.then<http.Response>((validTokens) {
          return http.post(url,headers: buildHeaders(validTokens.item2));
        });
      }
    });
  }

  Future<Response> sendDelete(String url,String appToken) async {
    var response = http.delete(url,headers: buildHeaders(appToken));
    return response.then<http.Response>((response) {
      if (HttpHelper.isSuccess(response))
        return response;
      else {
        var validTokens = refreshTokens(refreshToken,appToken);
        return validTokens.then<http.Response>((validTokens) {
          return http.delete(url,headers: buildHeaders(validTokens.item2));
        });
      }
    });
  }

  Future<http.Response> sendPut(String url,String appToken) async {
    var response = http.put(url,headers: buildHeaders(appToken));
    return response.then((response) {
      if (HttpHelper.isSuccess(response))
        return response;
      else {
        var validTokens = refreshTokens(refreshToken,appToken);
        return validTokens.then<http.Response>((validTokens) {
          return http.put(url,headers: buildHeaders(validTokens.item2));
        });
      }
    });
  }

  Future<http.Response> sendPatch(String url,String appToken) async {
    var response = http.patch(url,appToken);
        return validTokens.then<http.Response>((validTokens) {
          return http.patch(url,headers: buildHeaders(validTokens.item2));
        });
      }
    });
  }

  Map<String,String> buildHeaders(String appToken) {
    return {
      "Content-type": "application/json","Accept": "application/json","Authorization": "Bearer $appToken"
    };
  }

  Map<String,String> buildAuthHeader(String appToken) {
    return {"Authorization": "Bearer $appToken"};
  }

  Future<StreamedResponse> checkHandleExpiredJwtMultiPartRequest(
      MultipartRequest request,String appToken) async {
    var validTokens = new Tuple2<String,appToken);
    if (isTokenExpired(appToken)) validTokens = await refreshTokens(refreshToken,appToken);

    return sendMultiPartRequest(request,validTokens.item2);
  }

  Future<StreamedResponse> sendMultiPartRequest(
      http.MultipartRequest request,String appToken) async {
    setAuthHeader(request,appToken);
    var response = request.send();
    return response.then((response) {
      if (HttpHelper.isSRSuccess(response))
        return response;
      else {
        var validTokens = refreshTokens(refreshToken,appToken);
        return validTokens.then((validTokens) {
          setAuthHeader(request,validTokens.item2);
          return request.send();
        });
      }
    });
  }

  setAuthHeader(http.MultipartRequest request,String appToken) {
    var authHeader = buildAuthHeader(appToken);
    request.headers.addAll(authHeader);
  }
}

最终想法

我根本不知道为什么令牌的字符串突然变得无效。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)