signOut method
Implementation
Future<void> signOut(String redirectUri) async {
// Throw error is authentication status not found
final idToken = await _tokenStorage.idToken;
final httpClient = _httpClient ?? http.Client();
if (idToken == null) {
throw LogtoAuthException(
LogtoAuthExceptions.authenticationError, 'not authenticated');
}
try {
final oidcConfig = await _getOidcConfig(httpClient);
// Revoke refresh token if exist
final refreshToken = await _tokenStorage.refreshToken;
if (refreshToken != null) {
try {
await logto_core.revoke(
httpClient: httpClient,
revocationEndpoint: oidcConfig.revocationEndpoint,
clientId: config.appId,
token: refreshToken,
);
} catch (e) {
// Do Nothing silently revoke the token
}
}
await _tokenStorage.clear();
// Redirect to the end session endpoint it the platform is not iOS
// iOS uses the preferEphemeral flag on the sign-in flow, it will not preserve the session.
// For Android and Web, we need to redirect to the end session endpoint to clear the session manually.
if (kIsWeb || !Platform.isIOS) {
final signOutUri = logto_core.generateSignOutUri(
endSessionEndpoint: oidcConfig.endSessionEndpoint,
clientId: config.appId,
postLogoutRedirectUri: Uri.parse(redirectUri));
final redirectUriScheme = Uri.parse(redirectUri).scheme;
// Execute the sign-out flow asynchronously, this should not block the main app to render the UI.
await FlutterWebAuth2.authenticate(
url: signOutUri.toString(),
callbackUrlScheme: redirectUriScheme,
options: const FlutterWebAuth2Options(
intentFlags: ephemeralIntentFlags));
}
} finally {
if (_httpClient == null) {
httpClient.close();
}
}
}