Sign In with Apple is an authentication service by Apple similar to Facebook Login or Google Sign-In. Here are my notes on integrating it with website sign-in while working on a WordPress specific implementation.
Sign In with Apple is targeted at companies and services with existing iOS or macOS apps since the authentication flow uses the app icon from the primary App ID. While currently it appears to be working with new App IDs that don’t have a published app, that could change.
At core it uses standards such as OAuth and JWT which is awesome!
Requirements for Sign In with Apple
I didn’t have an Apple Developer membership until yesterday so I had to create and configure everything from scratch and it took a while. Here it is step by step:
- Apple Developer membership which costs $99 per year.
- App ID identifier for an iOS or macOS app (view documentation). All of the items below will be associated with this App ID.
- Service ID for the App ID with “Sign In with Apple” enabled and configured for a specific domain name and “Return URL”. Used as Client ID during the authentication flow.
- Authentication key with “Sign In with Apple” service enabled (view documentation). Used for signing the JSON Web Token (JWT) payload or
client_secret
during the token validation. - Configured domain names and email addresses to enable Apple to respond to the authentication requests for your domain name (documentation for domain and email relay configuration).
Note that the authentication flow uses the app icon from your main App ID so I’m not sure how Apple intends this to work with sites that don’t have an associated app. Here is the authentication prompt:
Two-Factor Authentication
Apple users accounts must have two-factor authentication enabled to actually sign-in with their Apple ID. Visit your Apple ID account on your device or on the web to enable the Two-Factor authentication.
Sign In with Apple JS
Sign In with Apple JS is a simple integration for adding the actual Sign In with Apple button or link to the page. All it does is generates the authentication link based on the Service ID and the return URL specified in the <meta>
tags in the page <head>
.
The official JS library will also enable native Sign In experience on Safari (from 30 minute mark of this Apple video):
Your website or app will still have to include custom logic to capture the authentication responses from Apple and create users or sign-in users based on the response data.
Sign In with Apple REST API
Sign In with Apple REST API is used for fetching the Apple’s public key for validating the authentication responses.
How to Review and Delete Authenticated Websites
Websites using your Apple ID for sign-in can be reviewed and removed under the Security section of your Apple ID profile:
Related Research and Links
Open Questions
How to Access User Name and Email?
Currently the id_token
in JWT response includes only subject or sub
field with a unique user identifier. The JWT reponse doesn’t include user’s name or email even when they’re requested in scope
.
{
"iss": "https://appleid.apple.com",
"aud": "net.kaspars.mycustomid",
"exp": 1559646675,
"iat": 1559646075,
"sub": "001111.532aa1f2229d4b70985bdbf913bb1ca1.2222"
}
Normally the authenticated name and email would be included as separate fields in the decoded id_token
.
An authenticated name and email will never be included as separate fields in the decoded id_token because (quote):
Instead they should be present in json response under separate key ‘user’. Note, it will be there only the first time user logs in as per (quote):
This is great insight, thank you for sharing Yura!
I believe that something changed since this article and email is now included in the idToken along with email_verified and optional is_private_email fields. These two additional fields are booleans transferred as strings. This first one was always true for me (Apple does verify all e-mails used in AppleID so I expect this field to contain true every time) and the second one appeared only when I decided not to share my own e-mail address with the website/app (therefore using Apple’s private relay and ending with is_private_email being always “true”).
I’m not sure if it stays, cause it’s not documented and I still haven’t released the Sign in with Apple feature to production, but all my test idToken’s included the email field.