How to Integrate Sign-In with Apple in React: A Step-by-Step Guide

How to Integrate Sign-In with Apple in React.png
Junaid
7 min read
Share
How to Integrate Sign-In with Apple in React.png

Sign-in with Apple is the authorization service provided by Apple which allows the user of your website to log in using their Apple ID and password. In this guide, I'll show you how to integrate it into your website.

Integrating Apple ID sign-in is not a straightforward process and can be challenging if you are doing this for the first time. To test our integration locally, we need to first set up a few tools. I couldn't find any articles discussing this stage, so I'm writing one for you.

To implement this, we won’t be working directly with the APIs provided by Apple Sign In with JS but to make our lives easier, we will be using the npm package that uses these APIs under the hood. So, let us begin.

Prerequisites

Before diving into the implementation, ensure you are enrolled in the Apple Developer Program and have an Apple Developer account. Just like any other Apple service, this program is also a paid program.

Install Ngrok

What is ngrok?

As per docs,

ngrok is a globally distributed reverse proxy that secures, protects and accelerates your applications and network services, no matter where you run them. You can think of ngrok as the front door to your applications.

That's a lot to take in. The basic idea behind ngrok is that it helps us expose our local environment to the internet. It generates a secure URL we can share without having to deploy it anywhere.

Why do we need it?

You may wonder, why we need to expose our local environment to test the integration locally. It turns out that, Apple Sign-In don’t support HTTP domains. While generating the credentials required for the sign-in process we need to provide a HTTPS domain, which is why we're using ngrok.

How to install ngrok?

ngrok has wonderful documentation to help you set up the ngrok CLI agent. Follow the instructions provide in this Getting Started guide.

Ensure that you create a static domain on your dashboard, by default ngrok provides random domain names every time you start the application. The final command to get your local application up and running may look like this -

ngrok http 8080 --domain <your static domain name>

After executing this command you can access your application at https://<your static domain name>. Try making some changes to your local code and the changes will automatically reflect on this domain. That is fantastic!

Generating Credentials

In this step, we need to create App ID, service ID, and register the domain we created above for Sign-In with Apple service.

Create a App ID

  1. Sign in into your Apple developer account and find "Certificates, Identifiers & Profiles.”
  2. Under the "Identifiers" section, click on the "+" button to create a new identifier.
  3. Choose "App IDs" and click "Continue.”
  4. Fill in the details, a description of the App ID and bundle ID ( this is usually in reverse domain format, for example com.example.app )
  5. Click "Continue" and then "Register" to create the App ID.

Create a Service ID

  1. Again in the "Identifiers" section, click on the "+" button, this time choose Service ID and click continue.
  2. Fill in the required information for your Service ID.
  3. Click "Continue" and then "Register" to create the Service ID.

Configure Sign-In with Apple

  1. In the "Identifiers" section, find your newly created Service ID.
  2. Click on it, and you will see the details of the Service ID.
  3. Under "Sign In with Apple," click on the "Configure" button.
  4. Fill in the necessary information
    1. Your Primary App ID will be the one we created earlier
    2. In the domains section, add the domain that we created in the ngrok step. In general, in this section we need to provide the domains that will use this service i.e. domain on which we want to implement sign in with Apple.
    3. The redirect URL is the URL to which Apple will redirect us after authentication is completed, along with the user data. This can be your backend endpoint handling the auth, for example https://example.com/auth/apple In this article we will be using the frontend URL of our application, the same domain the we generated in the ngrok step. We are doing this because we will be capturing the data on the client side, using the PopUp option ( more on this in next step )
  5. Click "Save" to apply the changes.

Handling sign-in on the frontend

We will be using react-apple-signin-auth npm package on our frontend, to install run -

yarn add react-apple-signin-auth

This package exports a React component that we can directly render in our application and pass the credentials as props -

// AppleSignIn.js

import AppleSigninButton from 'AppleSigninButton'

function AppleSignIn() {
	const handleSuccess = (data) => {
    const { authorization, user } = data

		// Here you can send data to your backend service and process the response
		// further based on your requirements
  }

	const authOptions = {
    clientId: <CLIENT_ID>, // This is your service ID
    scope: 'email name',
    redirectURI: <REDIRECT_URL>,
    nonce: 'nonce',
    usePopup: true, // important to catch up data on the frontend
  }

	return (
		<AppleSigninButton
       authOptions={authOptions}
       uiType="dark"
       className="apple-auth-btn"
       noDefaultStyle={false}
       onSuccess={handleSuccess}
       onError={(error: string) => console.error(error)}
    />
	)
}

Checkout react-apple-signin-auth for more available props and customisation. You may also be interest in reading human interface guildlines by Apple.

For the first time a user logs in to your website using their Apple ID, the structure of the response sent by Apple looks like this.

{
  "authorization": {
    "state": "state", // state string passed in authOptions
    "code": "code", // A single-use authentication code
    "id_token": "id_token" //  This is a JSON web token that we need to decode in backend 
  },
	// user information requested in scope option
  "user": {
    "email": "email",
    "name": {
      "firstName": "firstName",
      "lastName": "lastName"
    }
  }
}

Apple only sends the user object for the first time, for subsequent signs in by the same user, Apple only sends the authorization object. Ensure that the user information is saved in your database.

Handling sign-in on the backend

After Apple sends us the response including authorization and user object, we send this information to our backend to verify the token and store the user data in our database for future use.

We will use apple-signin-auth npm package to verify the token. To install, run

yarn add apple-signin-auth

Consider the resolver below, which handles our backend sign-in process. We import the the above-mentioned library and will use verifyIdToken method to decode the idToken sent by the client in frontend process.

I'm taking the liberty of passing the idToken and user as parameters directly to the oAuth method.

// oAuth.js

import appleSignin from 'apple-signin-auth';

export default const oAuth = async(idToken, user) => {
	const { sub, email, iss } = await appleSignin.verifyIdToken(idToken, {
      audience: <CLIENT_ID>,
      ignoreExpiration: true,
  });

	// here we check if we already have the user stored in the database
	// if there is no user we create a new user
}

We get a bunch of useful information after decoding the idToken

  • sub if the unique identifier for the user
  • email is, as you guessed, email of the user signed in
  • iss is the issuer-registered claim key, which in this case has value https://appleid.apple.com

You can find the full list of available information on apple-signin-auth Github repository.

At this stage, you can query your database to see if the user information is already available. If you don’t find the user that means this is the new user and we have the information about user’s name in the user object. Make sure you save this information in your database for future use.

I hope that was useful for you. Thank you for taking the time to read this. If you have any suggestion to improve this post, please let me know. You can find me on Twitter and Linkedin.

Share