49 lines
2.2 KiB
Dart
49 lines
2.2 KiB
Dart
// lib/services/auth/auth_interceptor.dart
|
|
//
|
|
// یک wrapper کوچک که قبل/بعد از هر درخواست API:
|
|
// - مطمئن میشود `RequestService.token` با access token جاری همگام است.
|
|
// - اگر access token در آستانهی انقضا است، قبل از درخواست refresh میکند.
|
|
// - در صورت دریافت 401 برای یک درخواست، یکبار refresh کرده و درخواست را
|
|
// مجددا اجرا میکند.
|
|
//
|
|
// این فایل عمدا lightweight است و به ساختار فعلی RequestService وابسته است
|
|
// تا کمترین تغییر در سرویسهای دیگر اعمال شود.
|
|
|
|
import 'package:didvan/services/auth/keycloak_auth_service.dart';
|
|
import 'package:didvan/services/auth/token_storage.dart';
|
|
import 'package:didvan/services/network/request.dart';
|
|
|
|
class AuthInterceptor {
|
|
AuthInterceptor._();
|
|
|
|
/// قبل از هر درخواست شبکهی نیازمند احراز هویت اجرا میشود.
|
|
///
|
|
/// اگر access token در دسترس نیست یا نزدیک به انقضاست، تلاش میکنیم
|
|
/// با refresh token تمدید کنیم.
|
|
static Future<void> ensureFreshToken() async {
|
|
if (TokenStorage.isAccessTokenValid) {
|
|
// فقط RequestService.token را sync میکنیم.
|
|
RequestService.token = TokenStorage.accessToken;
|
|
return;
|
|
}
|
|
// ignore: avoid_print
|
|
print('🔐 ensureFreshToken: access invalid -> attempting refresh '
|
|
'(hasRefresh=${TokenStorage.refreshToken != null})');
|
|
if (TokenStorage.refreshToken != null) {
|
|
await KeycloakAuthService.instance.refresh();
|
|
}
|
|
RequestService.token = TokenStorage.accessToken;
|
|
}
|
|
|
|
/// در صورت دریافت 401، یکبار تلاش به refresh میکنیم.
|
|
/// اگر موفق شد true برمیگرداند تا فراخواننده درخواست را retry کند.
|
|
static Future<bool> handleUnauthorized() async {
|
|
if (TokenStorage.refreshToken == null) return false;
|
|
final ok = await KeycloakAuthService.instance.refresh();
|
|
if (ok) {
|
|
RequestService.token = TokenStorage.accessToken;
|
|
}
|
|
return ok;
|
|
}
|
|
}
|