-
Notifications
You must be signed in to change notification settings - Fork 0
Apple
Nate River edited this page Sep 1, 2024
·
9 revisions
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.
- 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)
- Native iOS SDK
-
Sign in with Apple Plugin for Unity
which is based on native SDK and works only on iOS, tvOS and macOS
- Please visit Terminology section
- 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 toReturn URL
(which isAuthorization Middleware
) and provides an authorizationcode
(which can be later exchanged foraccess_token
),id_token
(if requested) and user info likefirst_name
,last_name
andemail
(if requested and only once at first sign-in) -
Authorization Middleware
transmitscode
and user info to your app (using deep linking when possible) - The app exchanges
code
foraccess token
(and may receiveid_token
as well) by creating JWT signed with p8 private key (ES256)
- For Android, iOS, macOS, Windows and UWP (platforms that support deep linking): COME UP WITH your
Custom URI scheme
(orProtocol
). It MUST contain the period symbol.
and small alphanumeric symbols only (no spaces, no undercores). In my example it issimple.oauth
, but it can bejelly.bean
(note thatCustom 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
insideAssets/Plugins/Android/
, SET yourCustom URI scheme
inside, like<data android:scheme="simple.oauth" />
. You can useAndroidManifestExample.xml
from the asset as an example, just copy, rename and edit. AGAIN, DON'T FORGET TO REPLACEsimple.oauth
with yourCustom URI scheme
! - For iOS and macOS: navigate to
Player Settings > Other > Configuration
and add yourCustom URI scheme
toSupported 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 setProtocol
(it MUST contain a period symbol, for examplesimple.oauth
), then enableInternetClient
inCapabilities
. - For Windows: navigate to
Player Settings
and enableResolution and Presentation > Force Single Instance
and setOther Settings > Api Compatibility Level = .NET Framework
- Visit App Store Connect, create a new account if needed
- Create a new app if needed, or use an existing app (currently sign-in works for unpublished apps)
- Visit Apple Developer > Certificates, Identifiers & Profiles
- Select your app and enable
Sign In with Apple
inCapabilities
(configure if needed) - Return to
Certificates, Identifiers & Profiles
and pressRegister a new identifier
- Select
Services IDs
and pressContinue
- Fill
Description
andIdentifier
and pressRegister
- Return to
Certificates, Identifiers & Profiles
and select your service identifier - Enable
Sign In with Apple
and pressConfigure
- Select
Primary App ID
, addhippogames.dev
toDomains and Subdomains
, addhttps://hippogames.dev/api/oauth/apple_redirect
toReturn URLs
(later you can replace it with your website) - Save changes
- Return to
Certificates, Identifiers & Profiles
and select theKeys
section - Perform
Register a New Key
withSign in with Apple
enabled and configured - Download p8 private key
- Copy
Key ID
(10 digits) - Copy
Team ID
at the top right (10 digits) - Return to Unity and configure
Resources/AppleAuthSettings.asset
- set
Client ID
which isIdentifier
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
- set
- Make sure that system time on your device is synchronized and has a valid Time Zone (it's important for
client_secret
generation)
-
Custom URI scheme
is picked, and it has a different value thansimple.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
- Check our
Example
scene and C# code ofExample.cs
- Create an instance of
AppleAuth
- Call
AppleAuth.SignIn
orAppleAuth.GetAccessToken
- Create
OnSignIn
orOnGetAccessToken
callbacks - Build and test
- Write a review on the Asset Store :)
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. |
- Call
AppleAuth.SignIn
withcaching: true
to return cachedUserInfo
. - Call
AppleAuth.GetAccessToken
instead ofAppleAuth.SignIn
if you need an access token only (and don't needUserInfo
). - You can use
AppleAuth.SavedAuth
to getTokenResponse
orUserInfo
(don't forget to check all values for null). - Disable debug logs for production by setting
AppleAuth.DebugLog = false
. - Check Manual cancellation if needed.
- 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.
- 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.