From 659e32dc8edb07357490285401e2e5b3106759b3 Mon Sep 17 00:00:00 2001 From: "mr.mojtaba" Date: Wed, 23 Jul 2025 08:44:14 +0330 Subject: [PATCH] fix : cancel token --- .../service/app_navigation_observer.dart | 9 ++-- packages/chicken/lib/data/di/chicken_di.dart | 4 +- .../remote/app_interceptor.dart | 41 ++++++++++++------- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/lib/infrastructure/service/app_navigation_observer.dart b/lib/infrastructure/service/app_navigation_observer.dart index 74cec1e..9ad7b38 100644 --- a/lib/infrastructure/service/app_navigation_observer.dart +++ b/lib/infrastructure/service/app_navigation_observer.dart @@ -18,25 +18,24 @@ class CustomNavigationObserver extends NavigatorObserver { _isWorkDone = true; await setupInjection(); } + tLog('CustomNavigationObserver: didPush - $routeName'); } - @override void didReplace({Route? newRoute, Route? oldRoute}) { super.didReplace(newRoute: newRoute, oldRoute: oldRoute); - - + tLog('CustomNavigationObserver: didReplace - ${newRoute?.settings.name}'); } @override void didPop(Route route, Route? previousRoute) { super.didPop(route, previousRoute); - + tLog('CustomNavigationObserver: didPop - ${route.settings.name}'); } @override void didRemove(Route route, Route? previousRoute) { super.didRemove(route, previousRoute); - + tLog('CustomNavigationObserver: didRemove - ${route.settings.name}'); } } diff --git a/packages/chicken/lib/data/di/chicken_di.dart b/packages/chicken/lib/data/di/chicken_di.dart index 3335a4d..bf68d7b 100644 --- a/packages/chicken/lib/data/di/chicken_di.dart +++ b/packages/chicken/lib/data/di/chicken_di.dart @@ -17,7 +17,8 @@ Future setupChickenDI() async { diChicken.registerLazySingleton( () => AppInterceptor( - refreshTokenCallback: () async {}, + //فعلا سامانه مرغ برای رفرش توکن چیزی ندارد + refreshTokenCallback: () async => null, saveTokenCallback: (String newToken) async { await tokenService.saveAccessToken(newToken); }, @@ -25,6 +26,7 @@ Future setupChickenDI() async { await tokenService.deleteTokens(); Get.offAllNamed(AuthPaths.auth, arguments: Module.chicken); }, + authArguments: Module.chicken, ), instanceName: 'chickenInterceptor', ); diff --git a/packages/core/lib/infrastructure/remote/app_interceptor.dart b/packages/core/lib/infrastructure/remote/app_interceptor.dart index 602d34f..8af53d5 100644 --- a/packages/core/lib/infrastructure/remote/app_interceptor.dart +++ b/packages/core/lib/infrastructure/remote/app_interceptor.dart @@ -11,6 +11,7 @@ class AppInterceptor extends Interceptor { final SaveTokenCallback saveTokenCallback; final ClearTokenCallback clearTokenCallback; late final Dio dio; + dynamic authArguments; static Completer? _refreshCompleter; static bool _isRefreshing = false; @@ -18,6 +19,7 @@ class AppInterceptor extends Interceptor { required this.saveTokenCallback, required this.clearTokenCallback, this.refreshTokenCallback, + this.authArguments, }); @override @@ -27,6 +29,10 @@ class AppInterceptor extends Interceptor { final newToken = await _refreshCompleter!.future; if (newToken != null && newToken.isNotEmpty) { options.headers['Authorization'] = 'Bearer $newToken'; + } else { + // اگر توکن جدید وجود نداشت، درخواست را رد کن + handler.reject(DioException(requestOptions: options, type: DioExceptionType.cancel)); + return; } } catch (_) { handler.reject(DioException(requestOptions: options, type: DioExceptionType.cancel)); @@ -44,11 +50,15 @@ class AppInterceptor extends Interceptor { handler.resolve(retryResult); return; } + // اگر رفرش توکن ناموفق بود، درخواست را رد کن + handler.reject(err); + return; } handler.next(err); } Future _handleUnauthorizedError(DioException err) async { + // اگر رفرش در جریان است، منتظر نتیجه‌ی آن بمان if (_isRefreshing && _refreshCompleter != null) { try { final newToken = await _refreshCompleter!.future; @@ -58,24 +68,28 @@ class AppInterceptor extends Interceptor { } } + // فقط یک بار فرآیند رفرش را شروع کن _isRefreshing = true; _refreshCompleter = Completer(); try { - final newToken = await refreshTokenCallback!(); + final newToken = await refreshTokenCallback?.call(); - if (!_refreshCompleter!.isCompleted) _refreshCompleter!.complete(newToken); - - if (newToken != null) { - await saveTokenCallback(newToken); // ✅ ذخیره توکن جدید + if (newToken != null && newToken.isNotEmpty) { + await saveTokenCallback(newToken); // ذخیره توکن جدید + _refreshCompleter!.complete(newToken); return await _retryRequest(err.requestOptions, newToken); } else { - await clearTokenCallback(); // ✅ پاک‌کردن توکن‌های قبلی + await clearTokenCallback(); // پاک کردن توکن‌های قبلی + _refreshCompleter!.complete(null); + _handleRefreshFailure(); return null; } } catch (e) { - if (!_refreshCompleter!.isCompleted) _refreshCompleter!.completeError(e); - await clearTokenCallback(); // ✅ پاک‌کردن توکن در صورت خطا + if (!_refreshCompleter!.isCompleted) { + _refreshCompleter!.completeError(e); + } + await clearTokenCallback(); // پاک کردن توکن در صورت خطا _handleRefreshFailure(); return null; } finally { @@ -92,10 +106,9 @@ class AppInterceptor extends Interceptor { void _handleRefreshFailure() { ApiHandler.cancelAllRequests("Token refresh failed"); - Future.delayed(const Duration(milliseconds: 100), () { - if (Get.currentRoute != '/Auth') { - Get.offAllNamed('/Auth'); - } - }); + + if (Get.currentRoute != '/Auth') { + Get.offAllNamed('/Auth', arguments: authArguments ?? 'Module.chicken'); + } } -} \ No newline at end of file +}