@invertase/react-native-apple-authentication

repository·main·Indexed 23 days ago

https://github.com/invertase/react-native-apple-authentication

A well-typed React Native library providing a complete Apple Authentication services API for iOS and Android apps. It includes support for AppleButton variants, credential state verification, and Android-specific configuration via Service IDs. The library supports React Native 0.60+ and requires Xcode 11+ for iOS 13+ support.

Tokens
14.8K
Snippets
20
Records
74
Agent score
81%

What's inside @invertase/react-native-apple-authentication

  1. Use identityToken and authorizationCode for server-side verification

    main

    To securely authenticate a user on your backend, use the following properties from the AppleRequestResponse object:

    1. identityToken: A JSON Web Token (JWT) signed by Apple. It contains the Issuer Identifier, Subject Identifier, Audience, Expiry Time, and Issuance Time. Use this to verify the user's identity directly.
    2. authorizationCode: A short-lived, one-time valid token. This code is bound to the specific transaction using the state attribute passed in the initial request. Your server can validate this code using the Apple identity service endpoint to provide proof of authorization.
  2. Use nonces for identity token verification

    main

    A nonce is a string passed to the identity provider to prevent replay attacks. It can be verified against the identity token returned in a successful AppleRequestResponse.

    • Automatic Nonce: If you do not provide a nonce, the library automatically generates one for you and includes it in the AppleRequestResponse.
    • Custom Nonce: You can provide your own nonce string via the nonce property.
    • Disabling Nonce: If your authentication provider does not support nonces, set nonceEnabled: false to disable the automatic behavior (defaults to true).
  3. Configure Android ResponseType and Scope

    main

    When configuring Apple Authentication on Android, you can specify the type of response and the amount of user information requested.

    ResponseType

    Determines the type of response requested. Valid values are:

    • code
    • id_token

    You can request one or both.

    Scope

    Determines the amount of user information requested from Apple. Valid values are:

    • name
    • email

    You can request one, both, or none.

  4. Configure Sign in with Apple in Apple Developer Console

    main

    You must configure your App ID and create a private key in the Apple Developer portal to support Apple Authentication:

    1. Enable Sign in with Apple for your Identifier

    1. Log in to the Apple Developer Console.
    2. Navigate to Identifiers in the sidebar.
    3. Select your project's App ID.
    4. Check the box for Sign in with Apple.
    5. Click Edit, select Enable as a primary App ID, and click Save.
    6. Click Save at the top of the screen to apply changes.

    Note: If you are using an existing primary App ID for a different project, choose the Group with existing primary App ID option and select your specific ID.

    2. Create a Sign in with Apple Key

    1. Navigate to Keys in the left-hand sidebar.
    2. Click to create a new key.
    3. Provide a name for the key.
    4. Check the box for Sign In with Apple and click Configure.
    5. Select your project's App ID as the primary App ID.
    6. Register the key, download it, and store it securely. This key is required for server-side verification.
  5. Integrate Apple Authentication with React Native Firebase

    main

    To use Apple Authentication with Firebase Auth, you must use @react-native-firebase/auth version v6.2.0 or higher.

    The workflow involves:

    1. Performing an Apple sign-in request using appleAuth.performRequest.
    2. Extracting the identityToken and nonce from the response.
    3. Creating a Firebase AppleAuthProvider credential using firebase.auth.AppleAuthProvider.credential(identityToken, nonce).
    4. Signing in or linking the user via firebase.auth().signInWithCredential(appleCredential) or linkWithCredential.

    Note: Always check for errors using appleAuth.Error (e.g., error.code === appleAuth.Error.CANCELED) to handle user cancellations.

    import React from 'react';
    import { View } from 'react-native';
    import { firebase } from '@react-native-firebase/auth';
    import { appleAuth, AppleButton } from '@invertase/react-native-apple-authentication';
    
    async function onAppleButtonPress() {
      // 1). start a apple sign-in request
      const appleAuthRequestResponse = await appleAuth.performRequest({
        requestedOperation: appleAuth.Operation.LOGIN,
        requestedScopes: [appleAuth.Scope.EMAIL, appleAuth.Scope.FULL_NAME],
      });
    
      // 2). if the request was successful, extract the token and nonce
      const { identityToken, nonce } = appleAuthRequestResponse;
    
      if (identityToken) {
        // 3). create a Firebase `AppleAuthProvider` credential
        const appleCredential = firebase.auth.AppleAuthProvider.credential(identityToken, nonce);
    
        // 4). use the created `AppleAuthProvider` credential to start a Firebase auth request
        const userCredential = await firebase.auth().signInWithCredential(appleCredential);
    
        console.warn(`Firebase authenticated via Apple, UID: ${userCredential.user.uid}`);
      } else {
        // handle this - retry?
      }
    }
    
    function SocialAuthButtons() {
      return (
        <View>
          {appleAuth.isSupported && (
            <AppleButton
              cornerRadius={5}
              style={{ width: 200, height: 60 }}
              buttonStyle={AppleButton.Style.WHITE}
              buttonType={AppleButton.Type.SIGN_IN}
              onPress={() => onAppleButtonPress()}
            />
          )}
        </View>
      );
    }
  6. Integrate Apple Authentication with Auth0 on iOS

    main

    To use Apple Authentication with Auth0, you must perform a token exchange. This involves:

    1. Using appleAuth.performRequest to initiate the login and request scopes like FULL_NAME and EMAIL.
    2. Verifying the credential state using appleAuth.getCredentialStateForUser.
    3. Sending a POST request to your Auth0 domain's /oauth/token endpoint using the urn:ietf:params:oauth:grant-type:token-exchange grant type.

    Required parameters for the Auth0 token exchange request:

    • grant_type: Must be urn:ietf:params:oauth:grant-type:token-exchange.
    • subject_token_type: Must be http://auth0.com/oauth/token-type/apple-authz-code.
    • subject_token: The authorizationCode obtained from the appleAuth.performRequest response.
    • client_id: Your Auth0 Client ID.
    • audience: Your Auth0 Audience.
    • user_profile: A JSON string containing the user's name and email.
    import { appleAuth } from '@invertase/react-native-apple-authentication';
    import axios from 'axios';
    import {
        auth0Client,
        auth0Domain,
        auth0Audience
    } from '../constants/constants';
    
    export default async function AppleAuthentication() {
        return new Promise(async (resolve, reject) => {
            const appleAuthRequestResponse = await appleAuth.performRequest({
                nonceEnabled: false,
                requestedOperation: appleAuth.Operation.LOGIN,
                requestedScopes: [appleAuth.Scope.FULL_NAME, appleAuth.Scope.EMAIL]
            });
    
            const credentialState = await appleAuth.getCredentialStateForUser(
                appleAuthRequestResponse.user
            );
    
            if (credentialState === appleAuth.State.AUTHORIZED) {
                const { 
                        fullName, 
                        authorizationCode, 
                        email 
                    } = appleAuthRequestResponse, 
                    { familyName, givenName } = fullName;
    
                await axios({
                    url: `https://${auth0Domain}/oauth/token`,
                    method: 'POST',
                    data: {
                        grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
                        subject_token_type: 'http://auth0.com/oauth/token-type/apple-authz-code',
                        scope: 'read:appointments openid profile email email_verified',
                        audience: auth0Audience,
                        subject_token: authorizationCode,
                        client_id: auth0Client,
                        user_profile: JSON.stringify({
                            name: {
                                firstName: givenName,
                                lastName: familyName
                            },
                            email: email
                        })
                    }
                })
                    .then(async (_auth0Response) => {
                        resolve({
                            message: 'success',
                            ..._auth0Response,
                            first_name: givenName,
                            last_name: familyName
                        });
                    })
                    .catch((_auth0Error) => {
                        reject({ error: true, message: 'error', detailedInformation: _auth0Error });
                    });
            }
        });
    }
  7. Configure Sign in with Apple in Xcode

    main

    To enable Apple Authentication in your iOS project, you must add the capability within Xcode:

    1. Open your project's .xcodeproj file in Xcode.
    2. Select your project target in the sidebar.
    3. Navigate to the Signing & Capabilities tab.
    4. Click the + Capability button.
    5. Select Sign in with Apple from the menu.
    6. Ensure you are signed in as a developer team to avoid signing errors.
  8. Prerequisites for @invertase/react-native-apple-authentication

    main

    Before using this library, ensure your environment meets the following requirements:

    • React Native: Version 0.60 or higher.
    • iOS Development (Mac only): A configured React Native iOS development environment.
    • Xcode: Version 11 or higher (required to support iOS 13+ where Sign In with Apple APIs are available).