Skip to content

Implement Apple login

To implement Apple login with the recipe code, complete the following steps in order.

Before you begin, complete the common prerequisites.

Overall flow

What you configure and call in each step is as follows. Use the native method on iOS and macOS and the browser-based method on Android and Windows.

Step Category What you do Applies to
1 External console Get credentials from Apple Developer All
2 Hive Console Register credentials and enable Apple login All
3 Hive Axyl SDK Install the authentication module and the login Add-on All
4 Hive Axyl SDK Initialize the SDK and register modules All
5 Recipe code Copy the common and method-specific recipe folders All
6 App code Prepare ClientId and DeviceKey All
7 Recipe code, App code Prepare the Apple credential source and connect the Hive Axyl relay URL All
8 Recipe code Call Apple login All
9 App code Handle login results All
10 App code Verify the behavior All
The email and name are provided only on the first login

In the native method, Apple provides the email and name only when the user logs in to this app for the first time. You cannot get them even if you request them again on later logins, so if you use these two values, you must save the result of the first login.

1. Set up Apple Developer

  • External console  Configure this in Apple Developer.


    Detailed procedure: Login integration

First, get the credentials to use for login from Apple Developer. The Hive Axyl authentication server needs these values to verify the tokens Apple issues.

After you get the Service ID, Team ID, and the key for login, prepare the following items depending on the method.

Method Items to prepare Where to check
Native method The Apple App ID and provisioning profile to use for the build. This App ID is a value that Apple issues and is different from the App ID you create in the Hive Console. Prepare the App ID and provisioning profile for iOS and macOS
Browser-based method The Return URL and domain of the Service ID. Register the relay URL that Hive Axyl operates, https://core-api.hiveaxyl.com/auth/v1/provider/callback, as the Return URL, and the domain of this address, core-api.hiveaxyl.com, as the domain. For how this address passes the authentication result to the app, see 7.3. Register the Return URL of the Service ID

2. Configure the Hive Console

Register the credentials you got in the Hive Console and enable Apple login. If the login method is disabled, the recipe call is rejected.

Setting Required Where to check
Register Apple login credentials Required Apple login credentials
Enable Apple login Required Login method types
Per-App ID login settings Optional Per-App ID login settings

The settings you register here apply to all App IDs in the project. To show different login methods only for specific App IDs, use the per-App ID login settings.

3. Install SDK modules and Add-ons

In your Unity project, install the authentication module and the Add-ons for the methods you support. An Add-on is a Hive Axyl SDK extension package that opens the Apple login screen or the browser login page, and the credential source you prepare in step 7 calls this Add-on.

Package Needed Role
com.com2usplatform.hiveaxyl.core Required SDK initialization and login session management
com.com2usplatform.hiveaxyl.auth Required Login with Apple credentials and token issuance
com.com2usplatform.hiveaxyl.auth.addon.apple Required for the native method Display of the Apple login screen
com.com2usplatform.hiveaxyl.auth.addon.webauth Required for the browser-based method Providing the browser web login session
com.unity.nuget.newtonsoft-json Required for the browser-based method JSON processing in ProviderLogin.WebAuth/
com.com2usplatform.hiveaxyl.storage Recommended Encrypted storage of DeviceKey and session tokens

If you do not install an Add-on package, the credential source that uses that Add-on is excluded from compilation, so you cannot use it in the app code. If you provide both methods, install both Add-ons.

The Apple login Add-on for the native method works on iOS 17.0 or later and macOS 15.0 or later. Set the minimum supported OS version of your Unity project to these versions or later. If the version is lower, the build is created, but the login screen does not appear on actual devices.

4. Initialize the SDK

  • Hive Axyl SDK  Call the Hive Axyl SDK from the app.


    Detailed procedure: Initialize modules

At the app's entry point, initialize the SDK once and register the authentication and token modules and the login Add-ons for the methods you support. The recipe does not initialize the SDK, so if you call it without initializing the SDK, it fails with a FailedPrecondition error.

The following is example initialization code that supports both the native and browser-based methods.

using Hive.Axyl.Auth;
using Hive.Axyl.Auth.Addon.Apple;
using Hive.Axyl.Auth.Addon.WebAuth;
using Hive.Axyl.Core;
using Hive.Axyl.Core.Unity;
using Hive.Axyl.Storage;

var config = CoreConfig.CreateBuilder("{appId}").Build();

HiveBootstrap.Initialize(config, builder =>
{
    builder
        .AddAuth()
        .AddToken()
        .AddSecureStorage()
        .AddAppleSignIn()
        .AddWebAuth();
});

For {appId}, enter the App ID you created in the Hive Console. If you support only one method, remove both the using directive and the registration method of the Add-on you do not use.

AddAppleSignIn() actually registers the module only on iOS and macOS, and AddWebAuth() registers the module on Android, iOS, macOS, and Windows. Both methods skip registration in the Unity Editor and do not cause an error when called on any OS, so you can register them without branching.

If your app already uses secure storage, you do not need to register AddSecureStorage(). Even in this case, the app must be able to read DeviceKey and the session tokens again after it restarts.

5. Install the recipe code

  • Recipe code  Copy the recipe code into your project.

A recipe is source code that you copy into your project instead of installing as a package. Copy the following items from the axyl-samples-unity repository to Assets/Recipes/ in your Unity project.

The items to copy and their roles are as follows.

  • Recipes.asmdef: Common assembly definition for recipes
  • AssemblyInfo.cs: Setting that exposes internal helpers to other recipe assemblies
  • Helper/: Common code shared by multiple recipes
  • ProviderLogin/: ProviderLoginRecipe, result types, and the credential source contract
  • ProviderLogin.Apple/: AppleCredentialSource and AppleSignInOptions for the native method
  • ProviderLogin.WebAuth/: AppleWebCredentialSource for the browser-based method and common browser login code

To call recipes from your app code, add the following assemblies to references in your app's assembly definition. The following example supports both methods. Because autoReferenced in the original Recipes.asmdef is false, your app assemblies do not reference it automatically.

{
  "name": "MyApp",
  "references": [
    "Hive.Axyl.Core",
    "Hive.Axyl.Auth",
    "Hive.Axyl.Auth.Addon.Apple",
    "Hive.Axyl.Auth.Addon.WebAuth",
    "Hive.Axyl.Storage",
    "Hive.Axyl.Samples.Recipes",
    "Hive.Axyl.Samples.Recipes.ProviderLogin",
    "Hive.Axyl.Samples.Recipes.ProviderLogin.Apple",
    "Hive.Axyl.Samples.Recipes.ProviderLogin.WebAuth"
  ]
}

Replace MyApp with the assembly name your app uses, and keep the existing settings and references. Unity assemblies do not pass references on transitively, so you must list here every assembly that your app code uses directly. Hive.Axyl.Core contains CoreConfig and HiveError, Hive.Axyl.Auth contains AddAuth() and AddToken(), Hive.Axyl.Auth.Addon.Apple contains AddAppleSignIn(), Hive.Axyl.Auth.Addon.WebAuth contains AddWebAuth(), and Hive.Axyl.Storage contains AddSecureStorage(). If you use only one method, you can remove the references to the Add-on and recipe assemblies you do not use, and if you do not register AddSecureStorage(), you do not need to list Hive.Axyl.Storage.

The code does not compile if you copy only the method-specific recipe folders

AppleCredentialSource and AppleWebCredentialSource implement the credential source contract in ProviderLogin/, and ProviderLoginRecipe uses the PKCE generation code and session preparation code in Helper/. Copy Helper/, Recipes.asmdef, AssemblyInfo.cs, and ProviderLogin/ together with the method-specific folders.

6. Prepare ClientId and DeviceKey

The ProviderLoginRecipe constructor takes ClientId and DeviceKey. ClientId is the value you checked in the common prerequisites, and the Hive Console issues it for each project. DeviceKey is the value the Hive Axyl authentication server uses to distinguish login sessions by device, and the app creates and stores it itself.

The recipe does not create or save DeviceKey, so create and manage it according to the following conditions.

  • A different value for each device. A random value such as a UUID is recommended
  • A value created and saved once on first launch and reused for every later login
  • A length of 22 to 64 characters
  • A value made up only of ASCII characters, excluding spaces and control characters
Do not overwrite it with a new DeviceKey just because the storage could not be read

The value may not be gone; only the read may have failed. First fix the storage access problem or try reading again.

You do not need to prepare PKCE values or nonce. On each call, the recipe creates a pair of PKCE values for the Hive Axyl authentication server and passes them separately to the login call and the token issuance call, and the credential source creates the nonce for the native method. The Apple authorization request in the browser-based method does not include PKCE, and the credential source itself also creates and verifies the state value that confirms that the callback is the response to this login request.

Passing an empty value throws an exception

If ClientId or DeviceKey is empty, the recipe throws ArgumentException instead of returning a result. It also throws ArgumentNullException when you pass the credential source as null. Before you pass a value read from storage as is, check whether it is empty.

7. Prepare the Apple credential source

  • Recipe code  Call the recipe code from the app.

    App code  Implement this in the app.


    Detailed procedure: Get Apple credentials

To tell the recipe which external authentication provider to log in with, you must create a credential source and pass it to the recipe. A credential source is an object that opens the Apple login screen or the browser login page and receives the user identifier and the authentication result. Choose and create the source that matches the running OS.

7.1. Native method

On iOS and macOS, use AppleCredentialSource. Specify what to request from Apple with AppleSignInOptions. The following example code requests both the email and the name.

using Hive.Axyl.Samples.Recipes;

var appleOptions = new AppleSignInOptions
{
    RequestEmail = true,
    RequestFullName = true,
};

IProviderCredentialSource source = new AppleCredentialSource(appleOptions);

If you need only the identifier, create it with new AppleCredentialSource(). If you omit the argument, the email and name are not requested. If you requested the email and name, have the app save the result of the first login.

7.2. Browser-based method

On Android and Windows, use AppleWebCredentialSource. This source opens the Apple login page with a web login session and exchanges the authorization code passed by the Hive Axyl relay URL in 7.3 for Apple credentials on the Hive Axyl authentication server. Create WebAuthOptions and the source with the following values.

Value Where to put it How to prepare
Apple authorization endpoint authorizeEndpoint of WebAuthOptions.Create() The value is https://appleid.apple.com/auth/authorize. See Apple's Request an authorization to the Sign in with Apple server.
Service ID clientId of WebAuthOptions.Create() The value you got in step 1
Hive Axyl relay URL redirectUri of WebAuthOptions.Create() https://core-api.hiveaxyl.com/auth/v1/provider/callback, which you registered as the Return URL of the Service ID in step 1
App callback URL Second argument of AppleWebCredentialSource Pass it only on Android. It uses the {appId}://oauth-callback format. For {appId}, enter the App ID you created in the Hive Console, not the Android package name. On Windows, omit it because the recipe reserves a local address itself.
using Hive.Axyl.Samples.Recipes;

var appleWebOptions = WebAuthOptions.Create(
    "https://appleid.apple.com/auth/authorize",
    "{appleServiceId}",
    "https://core-api.hiveaxyl.com/auth/v1/provider/callback");

// Android: Pass the app callback URL as well.
IProviderCredentialSource source =
    new AppleWebCredentialSource(appleWebOptions, "{appId}://oauth-callback");

// Windows: Omit the app callback URL.
// IProviderCredentialSource source = new AppleWebCredentialSource(appleWebOptions);

The Hive Axyl authentication server exchanges Apple's authorization code, so do not specify tokenEndpoint. If you specify tokenEndpoint, or if redirectUri is not an HTTPS address, is a local address, or contains a # fragment, the AppleWebCredentialSource constructor throws ArgumentException. ArgumentException is also thrown if the app callback URL is not an absolute URI or contains the # or | character, or if you pass an empty value to WebAuthOptions.Create(). This example does not specify a Scope, so it does not request the email and name.

7.3. Hive Axyl relay URL

In the browser-based method, Apple sends the authentication result to the Return URL as an HTTP POST request, so the app cannot receive this result directly. Therefore, the Hive Axyl relay URL that you registered as the Return URL in step 1 receives the result and passes it to the app, and the Hive Axyl authentication server creates the client secret needed for the authorization code exchange with the Private Key registered in step 2. You do not need to relay the authentication result or create the client secret on the app server. Register the Private Key only in the Hive Console, and do not keep it in the app or on the app server. The sequence from the Apple authorization request to the authorization code exchange is as follows.

  1. The recipe requests Apple authorization with the destination for the result added to the front of state as a prefix. On Android, it adds <app callback URL>|; on Windows, it adds <port>: of the local address the recipe reserved.
  2. Apple sends code or error, along with state, to the Hive Axyl relay URL.
  3. The Hive Axyl relay URL finds the destination from the prefix, and passes state with the prefix removed and code or error as query parameters to the app callback URL or the local address.
  4. The recipe checks that the returned state matches the value of this request and then exchanges the authorization code. At this time, it also sends the Hive Axyl relay URL used in the authorization request as the redirect URI.

On Android, register the App ID, which is the scheme of the app callback URL, in the app so that the WebAuth Add-on's callback screen receives it. If you do not register it, the result sent by the Hive Axyl relay URL does not reach the app, and login does not finish. For how to register it, see Prepare the Android redirect URI. If another login method already uses a different scheme, register both schemes according to Register multiple schemes. On Windows, you do not need to register it because the recipe reserves a local address itself.

7.4. Select the source by method

If you support both methods, use conditional compilation to select the source that matches the running OS. appleOptions is the value you created in 7.1, and appleWebOptions is the value you created in 7.2.

using Hive.Axyl.Samples.Recipes;

IProviderCredentialSource source;

#if UNITY_IOS || UNITY_STANDALONE_OSX
source = new AppleCredentialSource(appleOptions);
#elif UNITY_ANDROID
source = new AppleWebCredentialSource(appleWebOptions, "{appId}://oauth-callback");
#else
source = new AppleWebCredentialSource(appleWebOptions);
#endif

If you support only one method, create only that source.

8. Call Apple login

  • Recipe code  Call the recipe code from the app.

Pass the prepared credential source to LoginWithProviderAsync(). The recipe opens the Apple login screen or the browser login page to receive credentials, logs in with those credentials, and activates the session.

Also prepare a CancellationTokenSource so that you can stop waiting when the user closes the screen or cancels login.

using System.Threading;
using Hive.Axyl.Samples.Recipes;

var recipe = new ProviderLoginRecipe(clientId, deviceKey);

var cancellation = new CancellationTokenSource();
CancellationToken token = cancellation.Token;

LoginWithProviderOutcome outcome = await recipe.LoginWithProviderAsync(source, token);

When the screen is closed or the user selects cancel, call cancellation.Cancel(), and when the call finishes, clean up with cancellation.Dispose().

In the browser-based method on Windows, an external browser is used, so even if the user closes the browser, the recipe cannot detect it and keeps waiting. Add a cancel button to the login screen that calls cancellation.Cancel(), or specify a time limit such as new CancellationTokenSource(TimeSpan.FromMinutes(5)). To use TimeSpan, add using System;.

The recipe performs the following tasks internally.

Category Call Where to check
Recipe code Check that the authentication, token, and session modules are registered None
Add-on Native method: create nonce, show the Apple login screen, and get ProviderUserId and ProviderToken iOS and macOS
Add-on Browser-based method on Windows: reserve the local address that receives the callback with AllocateLoopbackRedirectUriAsync() Prepare the redirect URI
Recipe code Browser-based method: create state, add the prefix described in 7.3, and build the Apple authorization URL OSs other than iOS and macOS
Add-on Browser-based method: open the Apple login page with OpenAsync() and receive the callback passed by the Hive Axyl relay URL Open a web login session
Recipe code Browser-based method: verify the callback's state and get the authorization code OSs other than iOS and macOS
Hive Axyl SDK Browser-based method: exchange the authorization code for ProviderUserId and ProviderToken with ExchangeProviderTokenAsync(). Put the Hive Axyl relay URL used in the authorization request in RedirectUri, and do not send CodeVerifier Exchange external authorization codes
Recipe code Create a pair of PKCE values and pass them separately to the login call and the token issuance call Prepare the call parameter values
Hive Axyl SDK Pass the Apple credentials with LoginProviderAsync() and receive an authorization code Log in with an external authentication provider
Hive Axyl SDK Exchange the authorization code for an access token and a refresh token with IssueTokenAsync() Issue tokens and activate the session
Hive Axyl SDK Activate the login session with SetSession() Issue tokens and activate the session

The detailed procedures in the table above are written for calling the Hive Axyl SDK methods directly. Do not reimplement in the app the steps that the recipe handles for you, such as creating the nonce, state, and PKCE values. Refer to the procedures only to check what each call sends and receives.

If the modules are not registered, the recipe stops at the first step with a FailedPrecondition error. When Success is returned, the session is already ready, so do not call token issuance or session activation code separately. The session is activated only after usable tokens are received, so a failed attempt does not affect a session that was already open.

9. Handle login results

LoginWithProviderOutcome reports the login result through Status. FailedStep is a diagnostic value, so do not use it as a basis for branching the app's normal flow.

Status Value to check App handling
Success PlayerId, IsBlocked If the account is not under a usage restriction, go to the post-login screen.
BusinessOutcome BusinessOutcome, UnknownOutcomeCode Branch according to the rejection reason, and treat unknown values as failures and record them.
UserCanceled None The user closed the Apple login screen or declined consent, or closed the browser login page on Android, so return to the previous screen.
Failure Error.Code, Error.TraceId Record the technical problem and provide a retry flow.

If IsBlocked is true, login succeeded but the account is under a usage restriction. For restriction types and how to guide users, see Usage restriction.

PlayerId is the unique identifier that Hive Axyl assigns to each user. The same value is returned when the user logs in again with the same Apple account, so the app uses this value to distinguish each user's play data.

When you record an error, record FailedStep along with it. It has five values, None, Resolve, AcquireCredential, LoginProvider, and SessionSetup, and tells you at which step the process stopped.

9.1. Handle rejection reasons

A BusinessOutcome value is the reason the Hive Axyl authentication server rejected the login, so the guidance to show the user differs for each value. The recipe combines the rejection reasons from the login call, the token issuance call, and the external authorization code exchange call in the browser-based method into one value, so check all the relevant places.

The recipe renames the names written in the detailed procedures as follows when it returns them.

  • TerminateService: ServiceTerminated
  • InvalidClientId: InvalidClient
  • InvalidGrant: InvalidAuthorizationCode
  • InvalidGrantExpired: ExpiredAuthorizationCode
  • InvalidGrantCodeChallenge: CodeChallengeMismatch
  • InvalidGrantRefreshToken: InvalidRefreshToken

TemporarilyUnavailable is the only rejection reason that can succeed if you try again. Do not repeat the call immediately; retry with increasing intervals such as 1, 3, and 6 seconds.

9.2. Handle cancellation and unsupported environments

Cancellation and unsupported environments do not mean that the login was rejected, so do not present them to the user as failures. The recipe result and app handling for each situation are as follows.

Situation Recipe result App handling
The user closes the Apple login screen or declines consent UserCanceled Return to the previous screen
The user closes the browser login page on Android UserCanceled Return to the previous screen
The user selects cancel on the browser login page Failure with Internal Keep the login screen and let the user try again
The user closes the browser on Windows No result is returned End the wait with the cancel button or the time limit from step 8
The app cancels the wait with CancellationToken Failure with Cancelled Clean up the in-progress login screen and keep the login screen
The recipe is called on an OS where the Add-on the method needs is not registered Failure with Unavailable Offer another login method
The browser-based method is called on Android without an app callback URL Failure with FailedPrecondition Check that the app callback URL described in 7.2 is passed
The callback's state differs from the current login request Failure with PermissionDenied The callback was not started by this login, so keep the login screen and let the user try again

Do not display UnknownOutcomeCode or RawJson to users. Use them only when you need to record app errors, and do not assume that an unknown result is one you already know.

10. Verify the behavior

  • App code  Verify the behavior in the app.

Verify Apple login on actual devices and builds for the supported OSs. Verify the native method on iOS or macOS and the browser-based method on Android or Windows. In the Unity Editor, neither Add-on is registered and an Unavailable error is returned, so you cannot verify even the login screen.

  1. Run the app and start Apple login.
  2. Check that the Apple login screen or the browser login page appears, and complete the login. If the app does not return after login on Android, check the app callback scheme registration described in 7.3.
  3. Check Success and PlayerId, and check that the app moves to the post-login screen.
  4. Quit the app completely, run it again, log in with the same Apple account, and check that PlayerId is the same.
  5. Check that UserCanceled is returned when you close the Apple login screen in the native method, or the browser login page on Android. On Windows, check that Failure with Cancelled is returned through the cancel button or the time limit.

Next steps

To let logged-in users skip the login screen when they relaunch the app, see Automatic login.

To link another login method to an account that is already logged in, see the External authentication provider linking practical guide.

To let users leave the logged-in account and log in with another account, see the Logout practical guide.