class AuthorizationInterceptor extends QueuedInterceptorsWrapper { final TokenRepository _tokenRepository; final AuthorizationRepository _authorizationRepository; final RefreshTokenRepository _refreshTokenRepository; AuthorizationInterceptor({ required TokenRepository tokenRepository, required AuthorizationRepository authorizationRepository, required RefreshTokenRepository refreshTokenRepository, }) : _tokenRepository = tokenRepository, _authorizationRepository = authorizationRepository, _refreshTokenRepository = refreshTokenRepository; @override void onRequest( RequestOptions options, RequestInterceptorHandler handler, ) async { final String? token = _tokenRepository.access; if (token != null && token.isNotEmpty) { options.headers.addAll( { 'Authorization': 'Bearer $token', }, ); } handler.next(options); } @override void onError(DioError err, ErrorInterceptorHandler handler) async { if (err.response?.statusCode == 401) { final refreshToken = _tokenRepository.refresh; if (refreshToken == null || refreshToken.isEmpty) { _tokenRepository.clear(); _authorizationRepository.reauthorize(); return handler.next(err); } try { final AuthenticationEntity authenticationEntity = await _refreshTokenRepository.refresh(refreshToken); await _tokenRepository.update( access: authenticationEntity.accessToken, refresh: authenticationEntity.refreshToken, ); final RequestOptions requestOptions = err.response!.requestOptions; requestOptions.headers['Authorization'] = 'Bearer ${authenticationEntity.accessToken}'; final options = Options( method: requestOptions.method, headers: requestOptions.headers, ); final Dio dioRefresh = Dio( BaseOptions( baseUrl: requestOptions.baseUrl, headers: { 'accept': 'application/json', }, ), ); final response = await dioRefresh.request( requestOptions.path, data: requestOptions.data, queryParameters: requestOptions.queryParameters, options: options, ); return handler.resolve(response); } on DioError { if (err.response?.statusCode == 401) { await _tokenRepository.clear(); await _authorizationRepository.reauthorize(); } } } handler.next(err); } }