|
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( |
|
<String, String>{ |
|
'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: <String, String>{ |
|
'accept': 'application/json', |
|
}, |
|
), |
|
); |
|
final response = await dioRefresh.request<dynamic>( |
|
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); |
|
} |
|
} |
It run perfectly at first, but after first "refresh" success, the refreshToken function called as much as the number of failed request