Skip to content

Instantly share code, notes, and snippets.

@Collins-01
Last active June 25, 2024 20:21
Show Gist options
  • Select an option

  • Save Collins-01/f717ff3c2f3ebe8796b85a71c140f821 to your computer and use it in GitHub Desktop.

Select an option

Save Collins-01/f717ff3c2f3ebe8796b85a71c140f821 to your computer and use it in GitHub Desktop.
Refresh Token Implementation In Flutter, using Dio plugin
import 'package:bod_pay/core/core.dart';
import 'package:bod_pay/core/network_service/refresh_token_interceptor.dart';
import 'package:bod_pay/utils/utils.dart';
import 'package:dio/dio.dart';
import 'network_request_exception.dart';
class NetworkServiceInterceptors extends Interceptor {
final _logger = const AppLogger(NetworkServiceInterceptors);
final LocalCache cache = LocalCacheImpl();
@override
void onError(DioException err, ErrorInterceptorHandler handler) async {
_logger.e("Error from Dio: ",
functionName: "onError", error: err.toString());
if (err.response?.statusCode != null) {
_logger.e("Error ===> ${err.response}");
switch (err.response?.statusCode) {
case 400:
err = NetworkRequestException(
err.requestOptions,
err.response,
'Bad Request Error',
);
break;
case 401:
refreshToken(() => handler.next(err));
break;
case 403:
err = NetworkRequestException(
err.requestOptions,
err.response,
'Conflict Error',
);
break;
case 404:
err = NetworkRequestException(
err.requestOptions,
err.response,
'Not Found Error',
);
break;
case 409:
err = NetworkRequestException(
err.requestOptions,
err.response,
'Conflict Error',
);
break;
case 500:
err = NetworkRequestException(
err.requestOptions,
err.response,
'Internal Server Error',
);
break;
case 503:
err = NetworkRequestException(
err.requestOptions,
err.response,
'Internal Server Error',
);
break;
default:
err = NetworkRequestException(
err.requestOptions,
err.response,
'Request Unknown Error',
);
}
} else {
switch (err.type) {
case DioExceptionType.connectionError:
case DioExceptionType.sendTimeout:
case DioExceptionType.receiveTimeout:
case DioExceptionType.connectionTimeout:
err = NetworkRequestException(
err.requestOptions,
err.response,
'Network Error',
);
break;
case DioExceptionType.badCertificate:
err = NetworkRequestException(
err.requestOptions,
err.response,
'Network Error',
);
break;
case DioExceptionType.badResponse:
err = NetworkRequestException(
err.requestOptions,
err.response,
'Bad Request Error',
);
break;
case DioExceptionType.cancel:
err = NetworkRequestException(
err.requestOptions,
err.response,
'Network Error',
);
break;
case DioExceptionType.unknown:
err = NetworkRequestException(
err.requestOptions,
err.response,
'Network Error',
);
break;
}
}
return handler.next(err);
}
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
return handler.next(options);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
// TODO: implement onResponse
super.onResponse(response, handler);
}
}
void checkStatusCode(
RequestOptions requestOptions,
Response? response,
) async {
try {
switch (response?.statusCode) {
case 200:
case 204:
case 201:
break;
case 400:
throw NetworkRequestException(
requestOptions,
response,
'Bad Request Error',
);
case 401:
throw NetworkRequestException(
requestOptions,
response,
'UnAuthorized Error',
);
case 404:
throw NetworkRequestException(
requestOptions,
response,
'Not Found Error',
);
case 409:
throw NetworkRequestException(
requestOptions,
response,
'Conflict Error',
);
case 500:
throw NetworkRequestException(
requestOptions,
response,
'Internal Server Error',
);
default:
throw NetworkRequestException(
requestOptions,
response,
'Internal Server Error',
);
}
} on Failure {
rethrow;
}
}
// refresh token method
Future<void> refreshToken(Function()? callback) async {
final LocalCache localCache = LocalCacheImpl();
try {
print("REFRESHING TOKEN");
final token = await localCache.getToken();
if (token == null) {
// TODO: Logout and clear cache
NavigationService.instance
.navigateToReplaceAll(RoutePaths.loginOrRegisterView);
localCache.clearCache();
return;
}
final response = await http.get(Uri.parse(
"${APIEndPoints.base_url}${APIEndPoints.refreshToken}${token.refreshToken}"));
print("Response from calling refresh token => ${response.body}");
/// check if the tokens were returned, cache and navigate.
if (response.statusCode == 200) {
/// cache token
final decodedBody = jsonDecode(response.body) as Map<String, dynamic>;
final data = Token.fromMap(decodedBody['Data']);
localCache.saveToken(data);
return;
}
///check if the response code if 401, it means refresh token has expired, logout.
if (response.statusCode == 401) {
NavigationService.instance
.navigateToReplaceAll(RoutePaths.loginOrRegisterView);
localCache.clearCache();
throw CustomException(
errorTitle: "", msg: "session has expired, please relogin");
}
/// NO CONDITION IS MET, LOGOUT
else {
NavigationService.instance
.navigateToReplaceAll(RoutePaths.loginOrRegisterView);
localCache.clearCache();
throw CustomException(
errorTitle: "", msg: "session has expired, please relogin");
}
/// check response, cache tokens,
} catch (e) {
log("error refreshing token ==> $e");
callback?.call();
// NavigationService.instance
// .navigateToReplaceAll(RoutePaths.loginOrRegisterView);
// localCache.clearCache();
// throw CustomException(
// errorTitle: "", msg: "session has expired, please relogin");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment