From e71e4d633a521fb4e00e1866d32e1f496ad6b7a6 Mon Sep 17 00:00:00 2001 From: Vaibhav Surve Date: Mon, 23 Jun 2025 17:35:50 +0530 Subject: [PATCH] feat: Implement JWT token expiration handling and refresh logic in ApiService --- lib/helpers/services/api_service.dart | 46 ++++++++++++++++++++++++--- pubspec.yaml | 1 + 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/lib/helpers/services/api_service.dart b/lib/helpers/services/api_service.dart index bf3903e..27be07c 100644 --- a/lib/helpers/services/api_service.dart +++ b/lib/helpers/services/api_service.dart @@ -7,7 +7,7 @@ import 'package:logger/logger.dart'; import 'package:marco/helpers/services/auth_service.dart'; import 'package:marco/helpers/services/api_endpoints.dart'; import 'package:marco/helpers/services/storage/local_storage.dart'; - +import 'package:jwt_decoder/jwt_decoder.dart'; final Logger logger = Logger(); class ApiService { @@ -17,12 +17,48 @@ class ApiService { // === Helpers === - static Future _getToken() async { - final token = await LocalStorage.getJwtToken(); - if (token == null && enableLogs) logger.w("No JWT token found."); - return token; + static Future _getToken() async { + final token = await LocalStorage.getJwtToken(); + + if (token == null) { + if (enableLogs) logger.w("No JWT token found."); + return null; } + try { + // Check if the token is expired + if (JwtDecoder.isExpired(token)) { + _log("Access token is expired. Attempting refresh..."); + final refreshed = await AuthService.refreshToken(); + if (refreshed) { + return await LocalStorage.getJwtToken(); + } else { + _log("Token refresh failed. Logging out..."); + await LocalStorage.logout(); + return null; + } + } + + // Check if token is about to expire in < 2 minutes + final expirationDate = JwtDecoder.getExpirationDate(token); + final now = DateTime.now(); + final difference = expirationDate.difference(now); + + if (difference.inMinutes < 2) { + _log("Access token is about to expire in ${difference.inSeconds}s. Refreshing..."); + final refreshed = await AuthService.refreshToken(); + if (refreshed) { + return await LocalStorage.getJwtToken(); + } + } + + } catch (e) { + _log("Token decoding error: $e"); + } + + return token; +} + static Map _headers(String token) => { 'Content-Type': 'application/json', 'Authorization': 'Bearer $token', diff --git a/pubspec.yaml b/pubspec.yaml index 808debf..371d19d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -70,6 +70,7 @@ dependencies: percent_indicator: ^4.2.2 flutter_contacts: ^1.1.9+2 photo_view: ^0.15.0 + jwt_decoder: ^2.0.1 dev_dependencies: flutter_test: sdk: flutter