Front-End Web & Mobile

Enable Sign in with Apple on your app with AWS Amplify

This article was written by Anna Pfoertsch.


In this guide you will learn how to build a simple social sign in page for your Amplify project using the AWS Amplify Admin UI’s new Sign in with Apple (SIWA) functionality. SIWA supplements Amplify’s currently supported Identity Providers (Google, Facebook, and Amazon), and continues to allow developers to easily enable social sign-in to their applications, even without AWS experience.

AWS Amplify is the fastest and easiest way to build cloud-powered mobile and web apps on AWS. Amplify comprises a set of tools and services that enables front-end web and mobile developers to leverage the power of AWS services to build innovative and feature-rich applications.

Benefits:

  • Reach a broad base of Apple users with minimal setup
  • Manage users in the Amplify Admin UI
  • Setup prod and test environments easily
  • Use the Admin UI to manage users and groups (instead of having to login to the AWS console)

What we’ll learn:

  • How to deploy a React app with a simple social sign in web page
  • How to set up authentication directly from the Admin UI

Extra topics we’ll touch on

  • Managing your users from the Admin UI
  • Cloning your environment to set up a production workflow

What we’ll build:

  • A simple social sign in page backed by an Amplify-created Amazon Cognito user pool.

Prerequisites:

Get started – zero config frontend deployments

To get started, deploy your own web app or use the provided sample. For this blog post, we will deploy a basic create-react-app sample by clicking on the button below.

One Click Deploy to Amplify Console -

You will be asked to connect your GitHub account. Once connected, Amplify will fork the sample repository in your account and ask you to confirm deployment.

Collage of screenshots showing the Amplify app deploying in the AWS console

That’s it! This triggers a CI/CD pipeline as shown and within a minute or two your main branch should be hosted at an amplifyapp.com domain.

Taking a look at the new Sign in with Apple option in the Admin UI

Now that our app is hosted, let’s build a backend. Navigate to the backend environment tab and choose ‘Get started’. This will trigger a workflow to setup a default staging Amplify environment. Once setup, open staging’s Admin UI – the Admin UI is a visual interface to create and manage your backend, hosted outside the AWS console. This gives easier access (via email) to both developers and non-developers to update the Amplify backend.

Collage of screenshots showing the Amplify Admin UI deploy steps, with “Get started” and “Open admin UI” buttons highlighted

In the Admin UI, navigate to the “Authentication” tab to set up user authentication. Let’s take a look at the new Sign in with Apple option in the Admin UI to understand what exact information you need to enable your users to login with the Apple IDs. The required fields are:

  • Services ID
  • Team ID
  • Key ID
  • Private Key certificate

Screenshot of Admin UI showing the Authentication page with Sign in with Apple selected.

Take note of the redirect URL (outlined above in the dashed-yellow rectangle in the image above), we will need that later when creating a certificate.

Create an Identifier, Service ID, and Certificate in your Apple Developer Portal

We need to create an Identifier, Service ID, and Certificate to enable Sign in with Apple. It’s a lot of steps, but you need all of them so bear with me! Once you have successfully enrolled in the Apple Developer Program, select “Certificates, Identifiers & Profiles” in your Apple Developer Program account.

Screenshot of Apple Developer Program overview page

Once you’ve selected this, follow the below steps to create an App ID:

  1. On the left navigation bar, select Identifier.
  2. On the Identifiers page, select the + icon.
  3. On the Register a New Identifier page, select App IDs.
  4. On the Register an App ID page, under App ID Prefix, take note of the Team ID value.
  5. Provide a description in the Description text box and provide the bundleID of the iOS app.
    1. I gave mine the description “Amplify SIWA test app” and the Bundle ID “com.pananapread.SIWAtest”
  6. Under Capabilities, select Sign in with Apple.
  7. Select Continue, review the configuration, and then select Register.

Screenshot of creating an App ID in the Apple Developer Program site

Now we can move on to creating a Service ID:

  1. On the Identifiers page, on the right, select App IDs, and then select Services ID.
  2. Select the + icon and, on the Register a New Identifier page, select Services IDs.
  3. Provide a description in the Description text box and provide an identifier for the service id ending in “.sid”.
    1. I gave mine the description “Amplify SIWA test app” and added “.sid” to my Bundle ID to create my identifier, resulting in “com.pananapread.SIWAtest.sid”
  4. Continue and register the service id.

Screenshot of registering a Services ID on the Apple Developer Program site

Just a couple of more steps! It’s time to create your Certificate.

  1. Navigate once more to the Identifiers page, then select Services IDs from the dropdown on the right.
  2. Select the Service ID you just created in the above steps.
  3. Enabled Sign In with Apple and select Configure.

Screenshot of editing a Services ID on the Apple Developer Program site

  1. In the dialog box, select your previously created app ID under Primary App ID.
  2. Remember the redirect URL from your Admin UI? Time to paste that URL into Domains and Subdomains, minus https:// and /oauth2/idpresponse
  3. Paste the redirect URL again, with no modifications, into Return URLs.

Screenshot of configuring web authentication on the Apple Developer Program site

  1. Click Next, review the information, then select Done.
  2. On Edit your Services ID Configuration click Continue, review the information, then select Save.

You’re almost done! We just need to register a Key.

  1. On the main Certificates, Identifiers & Profiles, select Keys.
  2. On the Keys page, select the + icon.
  3. Provide a name for the key under Key Name.
  4. Enable Sign in with Apple and select Configure

Screenshot of registering a new key on the Apple Developer Program site

  1. Under Primary App ID select the app id that was created before.
  2. Click on Save
  3. On Register a New Key click Continue, review the information, then select Register.
  4. On the page you are redirected to take note of the Key ID and download the .p8 file containing the private key.

And you’re all set! Let’s get out of the Apple Developer portal and back to the Admin UI.

Setting up Sign in with Apple directly from the Admin UI’s Authentication page

Navigate to your Admin UI’s Authentication page again. Now it’s time to fill in all the sections:

  • Services ID should contain your service ID ending in “.sid“.
  • Team ID can be found from your App ID under “App ID Prefix”.
  • Your Key ID was created when you created your key and can be found there.
  • You should have already downloaded your Private Key Certificate after creating your key. You can either securely upload it, or paste the contents into the text box.

Screenshot of Admin UI showing the Authentication page with Sign in with Apple selected and the text fields filled out.

Once you’re done with this, you need to provide a “Sign-in & sign-out redirect URLs”. For testing purposes, I am setting mine to be http://localhost:3000/. Once you’ve done this, select “Save and deploy”.

Add social sign in to the React app

Let’s pull the Amplify configuration files into your source code by running:

amplify pull --appId <appId> --envName staging

Note: Replace <appID> with your app’s ID. The full command can easily be found by clicking “Local setup instructions” on the top right of your Admin UI and copying the pull command there.

Accept all the default values for the prompted questions.

You should see a new aws-exports.js file in the src/ folder with the Amazon Cognito resource information. Your aws-exports.js file should look something like this:

const awsmobile = {
  "aws_project_region": "YOUR_REGION",
  "aws_cognito_identity_pool_id": "YOUR_IDENTITY_POOL_ID",
  "aws_cognito_region": "YOUR_REGION",
  "aws_user_pools_id": "YOUR_USER_POOL_ID",
  "aws_user_pools_web_client_id": "YOUR_USER_POOL_WEB_CLIENT_ID",
  "oauth": {}
};

We have to configure your app to pick up the Amplify configuration generated by amplify push, as well as import the appropriate components. Do that by adding the following lines to the top of your index.js file:

import React, { useEffect, useState } from 'react';
import Amplify, { Auth, Hub } from 'aws-amplify';
import awsconfig from './aws-exports';

Amplify.configure(awsconfig)

To test out your Sign in with Apple social login, we’ll need to update the code in your App.js. Delete its current contents so you're left with just the below.

function App() {
    // TO DO 
}

export default App;

First things first, our App function will need to store the signed in user in an array. let’s add this.

const [user, setUser] = useState(null);

To continuously listen to the Amplify Hub for sign in events, we need to create the useEffect() function with the below cases.

useEffect(() => {
Hub.listen('auth', ({ payload: { event, data } }) => {
    switch (event) {
    case 'signIn':
    case 'cognitoHostedUI':
        getUser().then(userData => setUser(userData));
        break;
    case 'signOut':
        setUser(null);
        break;
    case 'signIn_failure':
    case 'cognitoHostedUI_failure':
        console.log('Sign in failure', data);
        break;
    }
});

We will also need the function getUser() to return the current user:

function getUser() {
  return Auth.currentAuthenticatedUser()
    .then(userData => userData)
    .catch(() => console.log('Not signed in'));
}

Finally, we want to return a page giving the user the option to log-in, or view their attributes on the UI. We are specifying provider as “SignInWithApple” to skip straight to the official Apple page rather than the Amazon Cognito federated sign-in.

return (
  <div style={{margin:"auto", width:"50%" }}>
    <p>? User: {user ? JSON.stringify(user.attributes) : 'None'}</p>
    {user ? (
      <button onClick={() => Auth.signOut()}>Sign Out</button>
    ) : (
      <button onClick={() => Auth.federatedSignIn({provider: 'SignInWithApple'})}>Sign in with Apple</button>
    )}
  </div>
);

Your App.js should look like the below:

import React, { useEffect, useState } from 'react';
import Amplify, { Auth, Hub } from 'aws-amplify';
import awsconfig from './aws-exports';

Amplify.configure(awsconfig);

function App() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    Hub.listen('auth', ({ payload: { event, data } }) => {
      switch (event) {
        case 'signIn':
        case 'cognitoHostedUI':
          getUser().then(userData => setUser(userData));
          break;
        case 'signOut':
          setUser(null);
          break;
        case 'signIn_failure':
        case 'cognitoHostedUI_failure':
          console.log('Sign in failure', data);
          break;
      }
    });

    getUser().then(userData => setUser(userData));
  }, []);

  function getUser() {
    return Auth.currentAuthenticatedUser()
      .then(userData => userData)
      .catch(() => console.log('Not signed in'));
  }

  return (
    <div style={{margin:"auto", width:"50%" }}>
      <p>? User: {user ? JSON.stringify(user.attributes) : 'None'}</p>
      {user ? (
        <button onClick={() => Auth.signOut()}>Sign Out</button>
      ) : (
        <button onClick={() => Auth.federatedSignIn({provider: 'SignInWithApple'})}>Sign in with Apple</button>
      )}
    </div>
  );
}

export default App;

You now have a simple web site utilizing Sign in with Apple with the Amplify Admin UI! ???

Alt: Gif screenshot of browser page demonstrating the UX of the Sign in with Apple flow

Connect deployed branch to the backend without CI/CD (automatic aws-exports.js generation)

Don’t forget to update your Amplify app using git push! This will trigger a build in your Amplify console, however you should observe the build fails with an error saying Cannot find file './aws-exports' in ./src. This happens because the Amplify config file (aws-exports.js) is not checked into your source repo. The Amplify CLI automatically adds the aws-exports file to the .gitignore to prevent merge conflicts associated with generated files.

Our new release from Amplify fixes this problem with automatic build-time Amplify config generation. In the Amplify console, hit Edit under the frontend branch to connect to a the staging backend.

Screenshot of AWS Amplify console showing a frontend environment branch named “main”

This opens a modal asking you to connect to a target backend. Since you are using staging as your sandbox environment to manually push backend updates, (either via the Admin UI or from the CLI by running amplify push), uncheck the full-stack CI/CD checkbox. Unchecking the box, turns off full-stack CI/CD allowing the app to autogenerate the Amplify config at build time while ensuring no updates are made to your backend at build time. Before hitting Save you will see instructions on how to setup a service role needed for Amplify to access your backend configuration.

Screenshot of AWS Amplify console showing the “Edit target backend” screen

Follow the instructions on how to to setup the service role. Once setup in the IAM console, return to the Amplify console to use that role within the app. Head over to App settings > General > Edit and pick the service role you just created from the dropdown.

Screenshot of AWS Amplify console showing the “Edit App Settings: General” screen

Now trigger a new build either by pushing some code, or by choosing Redeploy this version from the build details page. Your build should now pass successfully without making any updates to the backend. Try visiting the app and creating some data – you should successfully see data appear in the browser as well as in the Content tab in the Admin UI.

To learn more, see the Complete guide to full-stack CI/CD workflows with AWS Amplify.

?‍♀️ Extra tip #1: Manage your users from the Admin UI

Not a fan of the AWS Console? Your users can be easily managed from the Admin UI. To do so, select the User management section in the Admin UI. From here you can view, manage, and create new users.

Screenshot of the Amplify Admin UI showing the “User management” screen

To learn more, see Manage authentication for users and groups.

? Extra tip #2: Setup a production workflow

So far we have successfully deployed a branch, setup an app with authentication, and then connected the app backend (staging) to the deployed branch (main) without CI/CD. I can iterate on this backend by visiting the Admin UI to edit authentication, or add a new feature such as data content. This is however not a workflow we want for production – imagine manually adding a new field to your data model that breaks your app! Deploying to production should always be done via a CI/CD pipeline so your deployments are safe and can be tested in isolation from production. Amplify makes it easy to setup a production workflow.

First, clone staging environment and name it prod. The clone operation takes some time, but it is essentially creating a completely new app backend for you (with its own CloudFormation stack).

Screenshot of AWS Amplify console showing the Amplify app’s backend environments.It only has one named “Staging”

When the deployment completes you will have a new prod environment show up with its own database and GraphQL API.

Screenshot of AWS Amplify console showing the Amplify app’s backend environments.It only has two, one named “Staging” and the other named “Prod”

Now let’s setup our production frontend, Create a branch in your Git repo named prod and connect the branch in the Amplify console. This time, leave the full-stack CI/CD box checked and point the prod branch to the prod Amplify environment- this will give Amplify permission to deploy any updates to the backend that it finds in your checked in amplify folder.

Screenshot of AWS Amplify console showing a successful Github authorization

You are now setup to manage production deployments. To recap, here’s the workflow for getting new changes to production:

  1. Add a new field to your data model in the staging environment
  2. Run amplify pull to update your backend definition in your project so you can access/update the field.
  3. Push code to your main branch – with your app code changes you will also see updates to the amplify folder with references to the new field.
  4. Submit a pull request to merge main to prod branch. Review the PR with your team to make sure everything looks good. Ideally add end-to-end tests.
  5. Merge changes to prod – this will trigger an Amplify CI/CD build. The new field should now be visible in your prod data model.

To learn more, see the Complete guide to full-stack CI/CD workflows with AWS Amplify.

? Success!

Congratulations! You’ve got a fully functioning Amplify project up and running with Sign in with Apple authentication configured. With a few clicks, you were able to build out authentication for your Apple users, and even learn how to manage your users and set up a full-stack CI/CD workflow.

If you’re looking for more information, please review our documentation. If you have any feedback or enhancement requests, go ahead and create an issue in the Github repository.

Clean up

Now that you have finished this walk through, it's recommended that you delete your Amplify app if you aren't going to use it anymore. This ensures that your resources won't be abused in the event someone gains access to your project's credentials.

To delete all the local Amplify associated files and the Amplify project in the backend, run the following command:

$ amplify delete

or, go to your Amplify console, select the app you want to delete, and expand the dropdown in the top right to delete your app.

Screenshot of AWS Amplify console showing an Amplify app selected, and its “Actions” dropdown expanded. This shows the options “View app settings” and “Delete app”

This action cannot be undone. Once the project is deleted, you cannot recover it and will have to reconfigure the categories and the project configuration files if you need to use the project again.