Sign-in with Apple in an Angular Web App

Jimit Raval
JavaScript in Plain English
5 min readMay 9, 2021

--

Nowadays, most web applications have a social login feature. It is a more convenient way for end-users to authenticate securely with the system. And it will define your site as having user-friendly and better-than-ordinary authorization.

As we know, the most popular social authentications are signing in with Google and Facebook. And now, Apple has also jumped into this stack bucket to be a super cool third-party authorization provider.

In this article, we will cover the integration of signing in with Apple with Angular/React/Node or with any JavaScript framework.

Sounds great, right? Let’s begin…

The basic flow of sign in with Apple :

  1. Click “Sign In With Apple” button
  2. Your app’s current parent tab will open Apple’s login page in the new child tab with some metadata in the browser’s URL as query params.
  3. The user authenticates the identity after using Apple credentials and is redirected back to the URL which is the parent tab from where we had navigated.
  4. Apple will send a “FORM_POST” request with data to the redirect url specified in the Apple developers account configuration.
  5. User completes and verifies the sign-up flow for their site. And now you can apply your next request on process for an authorized user.

Here, I’m attaching simple diagram flow explanation of the above steps :

Basic Diagram of Sign In With Apple

Before diving into the code structure, first we need to configure our app on the Apple developer account, and from there, we will get the required metadata to construct the URL.

Required metadata from Apple developer account :

  1. Client ID: We will get this from Services IDs config as an identifier value. Example: “com.myapp.bundle.backend”
  2. Redirect URL: This is the URL which we will add in Web Authentication Configuration setup → Website URLs → Return / Redirect URLs. Example: https://www.abc.com/api/auth-apple-signin

Steps you need to perform to get metadata :

  • First, sign in to the Apple Developer Account and click on Certificates, Identifiers, and Profiles.
  • From the sidebar, choose Identifiers then click the blue plus icon.
  • Choose App IDs in this first step.
  • Choose platform as “iOS”, enter some descriptive words in the description and choose Bundle ID: “Explicit” and enter the value as shown in the following example. “com.myapp.bundle” → replace myapp text with your app_name.
  • Now scroll down and check the box next to “Sign In with Apple”.
  • Confirm and move to configure the next step which is Services IDs.
  • Enter the description and enter “com.myapp.bundle.backend” in the identifier field and also check the Sign In with Apple checkbox and click configure.
  • Now you are at the Web Authentication Configuration screen where you have to select your app from Primary App ID ( make sure you select the one which starts with your app name ).
  • Enter domain/sub-domain in Website URLs from which you will send the request to the Apple server ( you can add multiple URLs; do not add localhost or IP address as it is not allowed, for example: https://www.abc.com/).
  • Enter redirect URLs as well where Apple will send the response back after authenticating the user. Example: https://www.abc.com/api/auth-apple-signin

As we have completed the configuration and got the required metadata, let’s dive into the code.

  • In the first step, we need to construct the URL which is provided by Apple and redirect on it so the user can enter Apple credentials there :
  • URL: https://appleid.apple.com/auth/authorize/QUERY_PARAMS
  • We need to append some metadata as query params so the Apple server can validate our request from this data.
Meta Data :client_id -> com.myapp.bundle.backendredirect_uri -> https://www.abc.com/api/auth-apple-signin

response_type -> Type of response we want from apple

scope -> Required user’s data back after authenticate with apple

response_mode -> form_post ( Type format of response )
JavaScript Code

Apple will send data back to redirect_uri and it is handle at backend side. So, the question is how will we pass this data to Angular so our app can proceed to the next operation? And to solve this problem, we need to apply some custom stuff.

  • window.open(‘URL’): This method used to open a new child tab page from the current parent tab.
  • window.addEventListener(‘message’): This method will activate the listener in the parent tab which is waiting for data so when we get data from Apple in redirect_uri, after that, that data will be sent back as the response from the API to this listener as message event.
  • jwtHelper.decodeToken(event.data.id_token): Decoding this token will provide user’s data which includes email, sub, expire time.
  • Email can be shown/hidden as Apple provides a privacy option to users. So, for validating the identity of the user, we use the value of sub as it is constant and unique.

Keep in mind :

  1. Apple will send user’s firstName & lastName when the user signs in for the first time only in data form. So, we need to check for this object → event.data.user
  2. import { JwtHelperService } from ‘@auth0/angular-jwt → use this JWT helper for decoding tokens and to get values from them.

Now, let’s create one API route which will handle request from Apple.

Node API Code
  • API route will be the same as we provided in redirect_uri value.
  • Currently, the user is on the child tab which is Apple sign in and our parent tab is waiting/listening for the event to get data.
  • We need to pass the response as script tag and the window.opener method checks if the child tab is opened then closes it using window.close method and navigates back to our parent tab and provides data to the listening event.
  • window.opener.postMessage(data , parent_URL) : This method triggers ‘message’ event on our web-app and provide data.
  • API will get data in req.body as we have passed the query params response_mode: form_post to Apple.

You can apply your next operation on request after retrieving the data successfully in the event.

If you found this tutorial useful for integrating Apple sign-in into an Angular app, please feel free to support it by leaving some claps.

Eat > Sleep > Code > Repeat

Thank You!

More content at plainenglish.io

--

--