fix : cancel token

This commit is contained in:
2025-07-23 08:44:14 +03:30
parent 4fed369b5d
commit 659e32dc8e
3 changed files with 34 additions and 20 deletions

View File

@@ -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}');
}
}

View File

@@ -17,7 +17,8 @@ Future<void> setupChickenDI() async {
diChicken.registerLazySingleton<AppInterceptor>(
() => AppInterceptor(
refreshTokenCallback: () async {},
//فعلا سامانه مرغ برای رفرش توکن چیزی ندارد
refreshTokenCallback: () async => null,
saveTokenCallback: (String newToken) async {
await tokenService.saveAccessToken(newToken);
},
@@ -25,6 +26,7 @@ Future<void> setupChickenDI() async {
await tokenService.deleteTokens();
Get.offAllNamed(AuthPaths.auth, arguments: Module.chicken);
},
authArguments: Module.chicken,
),
instanceName: 'chickenInterceptor',
);

View File

@@ -11,6 +11,7 @@ class AppInterceptor extends Interceptor {
final SaveTokenCallback saveTokenCallback;
final ClearTokenCallback clearTokenCallback;
late final Dio dio;
dynamic authArguments;
static Completer<String?>? _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<Response?> _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<String?>();
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');
}
}
}
}