我想通过使用Flutter Dio包中的inceptor来使toki刷新。
我使用 onError 方法再次发出请求,但即使我使用 handler.reject(e),它也会进入无限循环。
class DioFetch {
Dio dio = Dio();
DioFetch() {
demoInceptor();
}
demoInceptor() async {
dio.interceptors.clear();
dio.interceptors.add(
InterceptorsWrapper(
onRequest: (options, handler) {
print("onRequest");
return handler.next(options);
},
onError: (DioError e, handler) async {
if (e.response != null) {
if (e.response?.statusCode == 401) {
print("statuscode: 401");
final refresh = await refreshToken();
if (refresh.statusCode == 200) {
RequestOptions options = e.requestOptions;
try {
var resp = await dio.request(e.requestOptions.path,
data: options.data,
cancelToken: options.cancelToken,
onReceiveProgress: options.onReceiveProgress,
onSendProgress: options.onSendProgress,
queryParameters: options.queryParameters);
return handler.resolve(resp);
} on DioError catch (error) {
return handler.reject(error);
}
} else {
return handler.reject(e);
}
}
} else {
return handler.next(e);
}
},
),
);
}
Future<Response> refreshToken() async {
//refresh token code. response dio
}
}
您可以通过两种方式修复它
1- 返回
error
而不是 handler.reject(e);
2- 不要使用相同的
dio
实例
创建另一个拦截器用于令牌刷新:
class TokenInterceptor extends Interceptor {
TokenInterceptor()
: dio = Dio(
BaseOptions(
baseUrl: EndPoints.baseUrl,
),
)..interceptors.addAll([
if (kDebugMode) PrettyDioLogger(),
]);
final Dio dio;
@override
void onError(DioError err, ErrorInterceptorHandler handler) {
// Do whatever you want
}
}
将其添加到app dio客户端:
dio = Dio()
..interceptors.addAll([
TokenInterceptor(),
]);
我认为你已经解决了你的问题,但我使用了另一种方法 要在使用
jwt_decoder
package 发送请求之前检查令牌是否过期,只需使用 bool isTokenExpired = JwtDecoder.isExpired(token);
检查令牌是否已过期或未过期,因此如果过期则返回 true
,并且 false
否则。
此外,您还可以使用此方法来获取到期日期DateTime expirationDate = JwtDecoder.getExpirationDate(token);
我认为这将是一个更好的解决方案,而不是“尝试”发送请求并获得 401 未经授权的错误响应,然后发送另一个请求来更新访问令牌,然后重新发送所需的请求