问题描述
问题
我的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 (将#修改为@)