Flutter Apple Auth Implementation
Published: 2024-01-16 09:14:25

NB: This article is not for a total beginner, as you need a basic understanding of how Flutter works and API consumption to fully comprehend this article.

### Table of Content

- ✨ [Introduction](#intro)
- 💪 [Flutter Auth Packages](#package)
- 🍏 [Apple accepted Data Flow](#apple)
- 😬 [Edge Cases](#edge)


###✨ Introduction <a name="intro"></a>

Apple Sign-In is a feature that enables users of your application to either sign up or sign in to your application using their iCloud account across all of your platforms while utilizing two-factor authentication. In this article, we will be looking at how to use the Flutter package to complete this feature on a mobile phone.


![Sign in with Apple](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r31cbo5jg54nztc2zkgd.png)

_Sign in with Apple flow: From Apple_

For full information about this `sign in with Apple`, please make reference to this site: [Authenticating users with Sign in with Apple](https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple)



###💪 Flutter Auth Packages <a name="package"></a>

To follow up with this article, we will be using the [sign_in_with_apple](https://pub.dev/packages/sign_in_with_apple) package. To avoid repetitions, you can follow the instructions on this package page.

In summary, select `Sign In with Apple Capability`.
NB: You can achieve this by simply:

- Going to your XCode, 
- Select `Signing & Capabilities` tab, 
- Click on the `Capability` beneath, a modal pops up. 
- Either scroll down or just search for `sign`, you should see the option, 
- Select to enable it.


![Xcode image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6uiungv3q9vl1cido8ta.png)



###🍏 Apple accepted Data Flow <a name="apple"></a>

Once a user has authenticated and either accepted to show or hide their email, they should be either registered or logged into your application (depending on what feature you're using it for) and not redirected to complete anything else, as that will make the review team flag your app during testing.

Best advice: make your signup endpoint either flexible or have a different endpoint for social OAuths. That way, you get to prompt the user to update their profiles once they're already logged into the system.

```dart
SignInWithAppleButton(
  onPressed: () async {
    final credential = await SignInWithApple.getAppleIDCredential(
      scopes: [
        AppleIDAuthorizationScopes.email,
        AppleIDAuthorizationScopes.fullName,
      ],
    );

    print(credential);

    // Now send the credential (especially `credential.authorizationCode`) to your server to create a session
    // after they have been validated with Apple (see `Integration` section for more information on how to do this)
  },
);
```

![Apple Agreement](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3lyc0nqwxmwpomzl9p9t.png)


![Auth Selection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3zuzcoihi4fhy8gwbpg3.png)

_Images from [Sign_in_with_apple](https://pub.dev/packages/sign_in_with_apple)_


###😬 Edge Cases <a name="edge"></a>

Apple's authentication is so security tight, that you as the developer will only get the user's `email` just once, and which is the initial time they used the apple service to sign into your application. If the log out of your application and tried to log back in, there's a tendency of it not working, as you might be expecting their email to continue.

To circumvent that, I'd suggest that you first check if the email is returned from the above code, if yes then continue with your normal implementation, else, send the `identityToken`, which is a value returned from the `apple` api call to your server. Then your server gets to decode that `jwt_token`, gets the email address and checks if user exist in the system.

PS: You can actually decode the `jwt_tpken` from you flutter side first and still re-use your supposed api.

This might be a security flaw, what do you think?