fix : cancel token
This commit is contained in:
@@ -18,25 +18,24 @@ class CustomNavigationObserver extends NavigatorObserver {
|
|||||||
_isWorkDone = true;
|
_isWorkDone = true;
|
||||||
await setupInjection();
|
await setupInjection();
|
||||||
}
|
}
|
||||||
|
tLog('CustomNavigationObserver: didPush - $routeName');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didReplace({Route? newRoute, Route? oldRoute}) {
|
void didReplace({Route? newRoute, Route? oldRoute}) {
|
||||||
super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
|
super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
|
||||||
|
tLog('CustomNavigationObserver: didReplace - ${newRoute?.settings.name}');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didPop(Route route, Route? previousRoute) {
|
void didPop(Route route, Route? previousRoute) {
|
||||||
super.didPop(route, previousRoute);
|
super.didPop(route, previousRoute);
|
||||||
|
tLog('CustomNavigationObserver: didPop - ${route.settings.name}');
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didRemove(Route route, Route? previousRoute) {
|
void didRemove(Route route, Route? previousRoute) {
|
||||||
super.didRemove(route, previousRoute);
|
super.didRemove(route, previousRoute);
|
||||||
|
tLog('CustomNavigationObserver: didRemove - ${route.settings.name}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ Future<void> setupChickenDI() async {
|
|||||||
|
|
||||||
diChicken.registerLazySingleton<AppInterceptor>(
|
diChicken.registerLazySingleton<AppInterceptor>(
|
||||||
() => AppInterceptor(
|
() => AppInterceptor(
|
||||||
refreshTokenCallback: () async {},
|
//فعلا سامانه مرغ برای رفرش توکن چیزی ندارد
|
||||||
|
refreshTokenCallback: () async => null,
|
||||||
saveTokenCallback: (String newToken) async {
|
saveTokenCallback: (String newToken) async {
|
||||||
await tokenService.saveAccessToken(newToken);
|
await tokenService.saveAccessToken(newToken);
|
||||||
},
|
},
|
||||||
@@ -25,6 +26,7 @@ Future<void> setupChickenDI() async {
|
|||||||
await tokenService.deleteTokens();
|
await tokenService.deleteTokens();
|
||||||
Get.offAllNamed(AuthPaths.auth, arguments: Module.chicken);
|
Get.offAllNamed(AuthPaths.auth, arguments: Module.chicken);
|
||||||
},
|
},
|
||||||
|
authArguments: Module.chicken,
|
||||||
),
|
),
|
||||||
instanceName: 'chickenInterceptor',
|
instanceName: 'chickenInterceptor',
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class AppInterceptor extends Interceptor {
|
|||||||
final SaveTokenCallback saveTokenCallback;
|
final SaveTokenCallback saveTokenCallback;
|
||||||
final ClearTokenCallback clearTokenCallback;
|
final ClearTokenCallback clearTokenCallback;
|
||||||
late final Dio dio;
|
late final Dio dio;
|
||||||
|
dynamic authArguments;
|
||||||
static Completer<String?>? _refreshCompleter;
|
static Completer<String?>? _refreshCompleter;
|
||||||
static bool _isRefreshing = false;
|
static bool _isRefreshing = false;
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ class AppInterceptor extends Interceptor {
|
|||||||
required this.saveTokenCallback,
|
required this.saveTokenCallback,
|
||||||
required this.clearTokenCallback,
|
required this.clearTokenCallback,
|
||||||
this.refreshTokenCallback,
|
this.refreshTokenCallback,
|
||||||
|
this.authArguments,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -27,6 +29,10 @@ class AppInterceptor extends Interceptor {
|
|||||||
final newToken = await _refreshCompleter!.future;
|
final newToken = await _refreshCompleter!.future;
|
||||||
if (newToken != null && newToken.isNotEmpty) {
|
if (newToken != null && newToken.isNotEmpty) {
|
||||||
options.headers['Authorization'] = 'Bearer $newToken';
|
options.headers['Authorization'] = 'Bearer $newToken';
|
||||||
|
} else {
|
||||||
|
// اگر توکن جدید وجود نداشت، درخواست را رد کن
|
||||||
|
handler.reject(DioException(requestOptions: options, type: DioExceptionType.cancel));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
handler.reject(DioException(requestOptions: options, type: DioExceptionType.cancel));
|
handler.reject(DioException(requestOptions: options, type: DioExceptionType.cancel));
|
||||||
@@ -44,11 +50,15 @@ class AppInterceptor extends Interceptor {
|
|||||||
handler.resolve(retryResult);
|
handler.resolve(retryResult);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// اگر رفرش توکن ناموفق بود، درخواست را رد کن
|
||||||
|
handler.reject(err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
handler.next(err);
|
handler.next(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Response?> _handleUnauthorizedError(DioException err) async {
|
Future<Response?> _handleUnauthorizedError(DioException err) async {
|
||||||
|
// اگر رفرش در جریان است، منتظر نتیجهی آن بمان
|
||||||
if (_isRefreshing && _refreshCompleter != null) {
|
if (_isRefreshing && _refreshCompleter != null) {
|
||||||
try {
|
try {
|
||||||
final newToken = await _refreshCompleter!.future;
|
final newToken = await _refreshCompleter!.future;
|
||||||
@@ -58,24 +68,28 @@ class AppInterceptor extends Interceptor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// فقط یک بار فرآیند رفرش را شروع کن
|
||||||
_isRefreshing = true;
|
_isRefreshing = true;
|
||||||
_refreshCompleter = Completer<String?>();
|
_refreshCompleter = Completer<String?>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final newToken = await refreshTokenCallback!();
|
final newToken = await refreshTokenCallback?.call();
|
||||||
|
|
||||||
if (!_refreshCompleter!.isCompleted) _refreshCompleter!.complete(newToken);
|
if (newToken != null && newToken.isNotEmpty) {
|
||||||
|
await saveTokenCallback(newToken); // ذخیره توکن جدید
|
||||||
if (newToken != null) {
|
_refreshCompleter!.complete(newToken);
|
||||||
await saveTokenCallback(newToken); // ✅ ذخیره توکن جدید
|
|
||||||
return await _retryRequest(err.requestOptions, newToken);
|
return await _retryRequest(err.requestOptions, newToken);
|
||||||
} else {
|
} else {
|
||||||
await clearTokenCallback(); // ✅ پاککردن توکنهای قبلی
|
await clearTokenCallback(); // پاک کردن توکنهای قبلی
|
||||||
|
_refreshCompleter!.complete(null);
|
||||||
|
_handleRefreshFailure();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!_refreshCompleter!.isCompleted) _refreshCompleter!.completeError(e);
|
if (!_refreshCompleter!.isCompleted) {
|
||||||
await clearTokenCallback(); // ✅ پاککردن توکن در صورت خطا
|
_refreshCompleter!.completeError(e);
|
||||||
|
}
|
||||||
|
await clearTokenCallback(); // پاک کردن توکن در صورت خطا
|
||||||
_handleRefreshFailure();
|
_handleRefreshFailure();
|
||||||
return null;
|
return null;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -92,10 +106,9 @@ class AppInterceptor extends Interceptor {
|
|||||||
|
|
||||||
void _handleRefreshFailure() {
|
void _handleRefreshFailure() {
|
||||||
ApiHandler.cancelAllRequests("Token refresh failed");
|
ApiHandler.cancelAllRequests("Token refresh failed");
|
||||||
Future.delayed(const Duration(milliseconds: 100), () {
|
|
||||||
if (Get.currentRoute != '/Auth') {
|
if (Get.currentRoute != '/Auth') {
|
||||||
Get.offAllNamed('/Auth');
|
Get.offAllNamed('/Auth', arguments: authArguments ?? 'Module.chicken');
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user