Skip to content

How to Sign In with Apple Using Capacitor

Sign in with Apple lets users authenticate with their Apple ID, offering a privacy-focused alternative to other social logins. Apple requires apps that offer third-party sign-in to also support Sign in with Apple. The Apple Sign-In plugin provides a straightforward way to integrate Apple Sign-In into your Ionic or Capacitor app on Android, iOS, and web. This guide walks you through setting up the required credentials, configuring the plugin for each platform, and implementing the sign-in flow.

Prerequisites

Before you begin, make sure you have the following:

Setting Up Apple Developer Credentials

Creating an App ID

If you haven't already, you need to create an App ID with the "Sign in with Apple" capability enabled:

  1. Go to the Apple Developer Portal and navigate to Certificates, Identifiers & Profiles > Identifiers.
  2. Click the + button to create a new identifier and select App IDs.
  3. Select App as the type and click Continue.
  4. Enter a Description (e.g. My Capacitor App) and a Bundle ID that matches your iOS app (e.g. com.example.app).
  5. Scroll down to the Capabilities section, check Sign in with Apple, and click Continue.
  6. Review the details and click Register.

Creating a Service ID (Android and Web)

On Android and web, Apple Sign-In uses a web-based OAuth flow. You need a Service ID to identify your app in this flow:

  1. In the Apple Developer Portal, navigate to Certificates, Identifiers & Profiles > Identifiers.
  2. Click the + button, select Services IDs, and click Continue.
  3. Enter a Description (e.g. My Capacitor App - Web) and an Identifier (e.g. com.example.app.web). This identifier will be used as the clientId when initializing the plugin.
  4. Click Continue, then Register.
  5. Click on the newly created Service ID and check Sign in with Apple.
  6. Click Configure next to Sign in with Apple.
  7. Under Domains and Subdomains, add the domain where your app is hosted (e.g. example.com). Enter just the domain without a protocol or trailing slash.
  8. Under Return URLs, add the redirect URL that the plugin will use after authentication (e.g. https://example.com/callback). The URL must use the https:// scheme.
  9. Click Save, then Continue, and Save again.

Configuring Your Capacitor App

Android

No additional configuration is required on Android beyond installing the plugin.

iOS

On iOS, you need to add the "Sign in with Apple" capability in Xcode:

  1. Open your project in Xcode by running npx cap open ios.
  2. Select your app target and navigate to the Signing & Capabilities tab.
  3. Click + Capability and search for Sign in with Apple.
  4. Add the capability. Xcode will automatically update your entitlements file.

Web

No additional configuration is required on Web beyond installing the plugin.

Implementing the Sign-In Flow

Initializing the Plugin

On Android and web, you need to initialize the plugin before calling any other method. Use initialize(...) and pass the Service ID you created earlier as the clientId:

import { AppleSignIn } from '@capawesome/capacitor-apple-sign-in';

const initialize = async () => {
  await AppleSignIn.initialize({
    clientId: 'com.example.app.web', // Your Service ID from the Apple Developer Portal
  });
};

On iOS, initialization is not required because the plugin uses the native Sign in with Apple framework directly.

Signing In

Use the signIn(...) method to start the Apple Sign-In flow. You can request scopes for the user's name and email:

import { AppleSignIn, SignInScope } from '@capawesome/capacitor-apple-sign-in';

const signIn = async () => {
  const result = await AppleSignIn.signIn({
    redirectUrl: 'https://example.com/callback', // Only required on Android and Web
    scopes: [SignInScope.Email, SignInScope.Name],
  });
  console.log('Identity token:', result.identityToken);
  console.log('Authorization code:', result.authorizationCode);
  console.log('User ID:', result.userId);
  console.log('Email:', result.email);
  console.log('Given name:', result.givenName);
  console.log('Family name:', result.familyName);
};

Warning

Apple only returns the user's name and email on the first sign-in. Subsequent sign-ins will not include this information, so make sure to store it on your backend after the initial authentication.

Handling Errors

If the user cancels the sign-in flow, the plugin throws an error with the code SIGN_IN_CANCELED. You can handle this to distinguish between user cancellation and actual errors:

import { AppleSignIn, SignInScope } from '@capawesome/capacitor-apple-sign-in';

const signIn = async () => {
  try {
    const result = await AppleSignIn.signIn({
      scopes: [SignInScope.Email, SignInScope.Name],
    });
    console.log('Identity token:', result.identityToken);
  } catch (error: any) {
    if (error.code === 'SIGN_IN_CANCELED') {
      console.log('User canceled sign-in');
    } else {
      console.error('Sign-in failed:', error);
    }
  }
};

Bonus: Verifying the Identity Token on the Backend

The identityToken returned by signIn(...) is a JSON Web Token (JWT) signed by Apple. You should always verify it on your backend before trusting the information. This ensures the token was actually issued by Apple and hasn't been tampered with.

To verify the token, fetch Apple's public keys from https://appleid.apple.com/auth/keys and validate the JWT signature and claims. Here's an example using the jose library for Node.js:

import { createRemoteJWKSet, jwtVerify } from 'jose';

const APPLE_JWKS_URL = new URL('https://appleid.apple.com/auth/keys');
const jwks = createRemoteJWKSet(APPLE_JWKS_URL);

const verifyIdentityToken = async (identityToken: string) => {
  const { payload } = await jwtVerify(identityToken, jwks, {
    issuer: 'https://appleid.apple.com',
    audience: 'com.example.app',
  });
  console.log('User ID:', payload.sub);
  console.log('Email:', payload.email);
};

The audience should match your app's Bundle ID (for tokens from iOS) or your Service ID (for tokens from Android and web). If your app uses both, verify against both values.

Conclusion

In this guide, we covered how to set up Apple Sign-In in a Capacitor app using the Apple Sign-In plugin. From creating App IDs and Service IDs in the Apple Developer Portal to configuring platform-specific settings and implementing the sign-in flow, the plugin handles the complexity across Android, iOS, and web so you can focus on building your app.

Explore the complete API Reference to see all available methods and options. Have suggestions or questions? Create an issue in our GitHub repository.

Stay connected with us on X and subscribe to our newsletter for the latest updates.