我正在尝试使用flutter实现JWT访问/刷新标记流。在我的访问标记过期后,我的QueuedInterceptor使用刷新标记获取新的访问标记。一切都正常,但它没有重试获取请求的资源并返回401。在刷新该页面后,资源加载。如何使用QueuedInterceptor实现重试?
class AuthInterceptor extends QueuedInterceptor {
final Dio _dio;
AuthInterceptor(this._dio);
@override
void onRequest(
RequestOptions options, RequestInterceptorHandler handler) async {
final accessToken = await storage.read(key: "accessToken");
final refreshToken = await storage.read(key: "refreshToken");
if (accessToken == null || refreshToken == null) {
const AuthState.unauthenticated();
final error = DioError(requestOptions: options, type: DioErrorType.other);
return handler.reject(error);
}
final accessTokenHasExpired = JwtDecoder.isExpired(accessToken);
final refreshTokenHasExpired = JwtDecoder.isExpired(refreshToken);
var _refreshed = true;
if (refreshTokenHasExpired) {
const AuthState.unauthenticated();
final error = DioError(requestOptions: options, type: DioErrorType.other);
return handler.reject(error);
} else if (accessTokenHasExpired) {
// regenerate new access token
_refreshed = await _regenerateAccessToken();
}
if (_refreshed) {
options.headers["Authorization"] = "Bearer $accessToken";
return handler.next(options);
} else {
final error = DioError(requestOptions: options, type: DioErrorType.other);
return handler.reject(error);
}
}
Future<bool> _regenerateAccessToken() async {
try {
var dio = Dio();
final refreshToken = await storage.read(key: "refreshToken");
final response = await dio.post(
"https://localhost:7104/api/Login/Token/Refresh",
options: Options(headers: {"Authorization": "Bearer $refreshToken"}),
);
if (response.statusCode == 200 || response.statusCode == 201) {
final newAccessToken = response.data["accessToken"];
storage.write(key: "accessToken", value: newAccessToken);
return true;
} else if (response.statusCode == 401 || response.statusCode == 403) {
const AuthState.unauthenticated();
return false;
} else {
return false;
}
} on DioError {
return false;
} catch (e) {
return false;
}
}
}
这就是我用拦截器创建请求的方式。如果我的访问令牌过期,拦截器将抛出401:
final dio = Dio();
dio.options.baseUrl = authenticationBackend;
dio.interceptors.addAll([
AuthInterceptor(dio),
]);
var response = await dio.get('$host/animals');
1条答案
按热度按时间bvn4nwqk1#
然后用它