Skip to content
Nate River edited this page Sep 1, 2024 · 9 revisions

Welcome to Simple Apple Sign-In wiki!

The asset provides [Sign in with Apple] using OAuth 2.0 for Android, iOS, Windows, macOS, Universal Windows Platform (UWP) and WebGL apps made with Unity.

Benefits

  • Cross-platform user auth for cross-platform games and apps
  • No plugins, no 3rd party auth libs, no dependencies
  • No impact to build size
  • Get access tokens for integration with other Apple services
  • More security for client-server apps (get an access token on a client, get all user data on a server to avoid tampering)
  • SFSafariViewController is used on iOS (required by App Store review)
  • Deep linking for Windows (UNITY_STANDALONE_WIN)

Alternatives

  • Native iOS SDK
  • Sign in with Apple Plugin for Unity which is based on native SDK and works only on iOS, tvOS and macOS

Terminology

Understanding how it works

  • Your app navigates users to Apple Authorization Endpoint in a web browser
  • Users perform sign-in using their login and password
  • Apple Authorization Endpoint redirects users to Return URL (which is Authorization Middleware) and provides an authorization code (which can be later exchanged for access_token), id_token (if requested) and user info like first_name, last_name and email (if requested and only once at first sign-in)
  • Authorization Middleware transmits code and user info to your app (using deep linking when possible)
  • The app exchanges code for access token (and may receive id_token as well) by creating JWT signed with p8 private key (ES256)

Preconditions

  • For Android, iOS, macOS, Windows and UWP (platforms that support deep linking): COME UP WITH your Custom URI scheme (or Protocol). It MUST contain the period symbol . and small alphanumeric symbols only (no spaces, no undercores). In my example it is simple.oauth, but it can be jelly.bean (note that Custom URI scheme is not the same as your actual package name or bundle id).
  • For Android, iOS, UWP: enable deep linking as described in Unity documentation or as described below.
  • For Android: create AndroidManifest.xml inside Assets/Plugins/Android/, SET your Custom URI scheme inside, like <data android:scheme="simple.oauth" />. You can use AndroidManifestExample.xml from the asset as an example, just copy, rename and edit. AGAIN, DON'T FORGET TO REPLACE simple.oauth with your Custom URI scheme!
  • For iOS and macOS: navigate to Player Settings > Other > Configuration and add your Custom URI scheme to Supported URL schemes. In Xcode, make sure that the URL scheme is added (Register your URL scheme).
  • For Universal Windows Platform: navigate to Player Settings > Publishing Settings and set Protocol (it MUST contain a period symbol, for example simple.oauth), then enable InternetClient in Capabilities.
  • For Windows: navigate to Player Settings and enable Resolution and Presentation > Force Single Instance and set Other Settings > Api Compatibility Level = .NET Framework

Setup steps

  1. Visit App Store Connect, create a new account if needed
  2. Create a new app if needed, or use an existing app (currently sign-in works for unpublished apps)
  3. Visit Apple Developer > Certificates, Identifiers & Profiles
  4. Select your app and enable Sign In with Apple in Capabilities (configure if needed)
  5. Return to Certificates, Identifiers & Profiles and press Register a new identifier
  6. Select Services IDs and press Continue
  7. Fill Description and Identifier and press Register
  8. Return to Certificates, Identifiers & Profiles and select your service identifier
  9. Enable Sign In with Apple and press Configure
  10. Select Primary App ID, add hippogames.dev to Domains and Subdomains, add https://hippogames.dev/api/oauth/apple_redirect to Return URLs (later you can replace it with your website)
  11. Save changes
  12. Return to Certificates, Identifiers & Profiles and select the Keys section
  13. Perform Register a New Key with Sign in with Apple enabled and configured
  14. Download p8 private key
  15. Copy Key ID (10 digits)
  16. Copy Team ID at the top right (10 digits)
  17. Return to Unity and configure Resources/AppleAuthSettings.asset
    • set Client ID which is Identifier from Step 7
    • set Team ID from Step 16
    • set Private Key Id from Step 15
    • set Private Key (copy entire content of the p8 file downloaded in Step 14)
    • set Custom URI Scheme from Preconditions
  18. Make sure that system time on your device is synchronized and has a valid Time Zone (it's important for client_secret generation)

Checklist

  • Custom URI scheme is picked, and it has a different value than simple.oauth
  • Custom URI scheme is set in 3 places: [1] Apple service ID (Return URLs), [2] Resources/AppleAuthSettings.asset, [3] your application manifest (AndroidManifest.xml for Android, Supported URL schemes for iOS, Protocol for UWP)
  • Resources/AppleAuthSettings.asset contains valid settings different from that come with the asset

Usage

  1. Check our Example scene and C# code of Example.cs
  2. Create an instance of AppleAuth
  3. Call AppleAuth.SignIn or AppleAuth.GetAccessToken
  4. Create OnSignIn or OnGetAccessToken callbacks
  5. Build and test
  6. Write a review on the Asset Store :)

API reference for AppleAuth class

Method Arguments Description
AppleAuth (constructor) AppleAuthSettings settings = null A constructor that accepts an instance of AppleAuthSettings. If Null is passed, it will load default settings from Resources (AppleAuthSettings scriptable object).
SignIn Action<bool, string, UserInfo> callback, bool caching = true Performs sign-in and returns an instance of UserInfo with callback. If caching is True, it will return the previously saved UserInfo.
SignOut bool revokeAccessToken = false Performs sign-out. Can revoke Access Token if requested.
GetTokenResponse Action<bool, string, TokenResponse> callback Returns an instance of TokenResponse which contains AccessToken and other related information (expiration, type and other). It may also contain IdToken (JWT), if requested with openid scope, which contains information about the user.
TryResume Refer to code This can be called on app startup to continue OAuth. In some scenarios, the app may be terminated while the user performs sign-in on Google website.
SignInAsync Async version of SignIn.
GetTokenResponseAsync Async version of GetTokenResponse.

Best practices

  • Call AppleAuth.SignIn with caching: true to return cached UserInfo.
  • Call AppleAuth.GetAccessToken instead of AppleAuth.SignIn if you need an access token only (and don't need UserInfo).
  • You can use AppleAuth.SavedAuth to get TokenResponse or UserInfo (don't forget to check all values for null).
  • Disable debug logs for production by setting AppleAuth.DebugLog = false.
  • Check Manual cancellation if needed.

Unity Authentication Service

Security concerns

  • Please refer to User data disclosure
  • It's recommended to deploy your own trusted Authorization Middleware to handle sensitive data. Please refer to Authorization Middleware article.
  • Another concern is storing p8 Private Key inside the app, and the solution is moving all code responsible for exchanging access tokens (AppleAuth.PerformCodeExchange) to your backend.
  • You can implement id_token signature validation.

Known issues

  • Please visit Common issues section
  • Apple only returns the user object the first time the user authorizes the app. Validate and persist this information from your app to your server. Subsequent authorization requests do not contain the user object, however, the user's email is provided in the identity token for all requests (more info). For debugging, you can get user name again by visiting Apple ID > Sign-In and Security > Sign in with Apple > Select app > Stop using Sign in with Apple. Alternatively, Apple will return user name again after revoking access tokens.
  • The App Store review team may reject your app if you don't use native SDK for Sign in with Apple.
  • BouncyCastle.Crypto.dll is used to create JWT signed with ES256 (client_secret required for making API calls). This results in build size overhead. No .NET alternatives found yet.
  • Validating id_token signature is not implemented yet. BouncyCastle.Crypto.dll can be used for this.
  • When exchanging an auth code, it's important to have valid system time on client's device, otherwise you will get invalid_client error.

Support

Links

Clone this wiki locally