Follow up from #34, as suggested in PR; relates to #30
Current (incl. Web/Android support)
final credentials = await SignInWithApple.requestCredentials(
requests: [
PasswordAuthorizationRequest(),
AppleIDAuthorizationRequest(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
),
],
webAuthenticationOptions: WebAuthenticationOptions (…),
);
Issues with the current implementation
I think exposing an API that accepts multiple requests in order, while there is only one useful order (keychain first, Apple ID second), is not helping.
Furthermore we have an issue with the keychain result, which could return credentials which are not valid anymore. To find out that that is the case the parent application would need to try them first, and in an error case either suggest the user to recover their account via e-mail, or call requestCredentials
again without the password request.
Possible approach
Beyond just simplifying the above API (remove the extremely verbose options), I would prefer to split up keychain and Apple ID authentication into separate APIs (as also suggested by @HenriBeck in #30 (comment)).
Having no password stored in keychain should not be an error in that case (just return null
), and the calling app can cleanly handle just the password scenario in whatever way it wants.
Furthermore the Apple ID scenario could be simplified into:
final credentials = await SignInWithApple.requestCredentials(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
webAuthenticationOptions: WebAuthenticationOptions (…),
);
With regards to the webAuthenticationOptions
I wonder if we should stick to the static
methods, or provide some wrapper class, where the consumer can pass their configuration when creating the instance. As the webAuthenticationOptions
parameter is only needed in a single case (and only on some platforms), it might be fine to keep it on that specific request.
The full consumer side would then look like this:
// Optional, if the app wants to fallback to web credentials and hasn't already checked keychain by some other method
final keychainCredentials = await SignInWithApple.getKeychainCredential();
if (keychainCredentials != null) {
final loginResult = await loginClient.login(keychainCredentials.username, keychainCredentials.password);
if (loginResult.success) {
return;
}
}
final credentials = await SignInWithApple.requestCredentials(
scopes: [AppleIDAuthorizationScopes.email, AppleIDAuthorizationScopes.fullName],
webAuthenticationOptions: WebAuthenticationOptions (…),
);