getToken method
Implementation
Future<String?> getToken({bool forceRefresh = false}) async {
/// This is important to ensure we have the latest tokens before performing
/// checks or refresh operations with the tokens.
/// This is especially important for apps with concurrent background tasks
/// using isolates that don't have access to the latest cached state
await _store.reloadAuthState();
// Return existing token if authenticated and not forcing refresh
if (!forceRefresh && await isAuthenticated()) {
_kindeApi.setBearerAuth(_bearerAuth, _store.authState?.accessToken ?? '');
return _store.authState?.accessToken;
}
// Proceed with token refresh
kindeDebugPrint(
methodName: 'getToken',
message: 'Token refresh initiated',
context: {
'trigger': forceRefresh ? 'manual' : 'auto',
'hasRefreshToken': authState?.refreshToken != null,
},
);
final version = await _getVersion();
final versionParam = 'Flutter/$version';
try {
if (authState?.refreshToken == null) {
kindeDebugPrint(
methodName: 'getToken',
message: 'No refresh token available',
);
throw KindeError(code: KindeErrorCode.sessionExpiredOrInvalid.code);
}
final data = await _tokenApi.retrieveToken(
versionParam,
_store.authState!.createRequestTokenParam()
..putIfAbsent(_clientIdParamName, () => _config!.authClientId));
_store.authState = AuthState.fromJson(data as Map<String, dynamic>);
_kindeApi.setBearerAuth(_bearerAuth, _store.authState?.accessToken ?? '');
kindeDebugPrint(
methodName: 'getToken',
message: 'Token refresh successful',
context: {
'expiresAt': _store.authState?.accessTokenExpirationDateTime
?.toIso8601String(),
},
);
return _store.authState?.accessToken;
} catch (e, st) {
kindeDebugPrint(
methodName: 'getToken',
message: 'Token refresh failed',
context: {'error': e.toString()},
);
throw KindeError.fromError(e, st);
}
}