I recently had to implement “Sign in with Apple” for one of our customers and at first glance it was pretty straight forward but when I needed to validate the user on the server side I was left empty handed. I did some search on Google and ended up piecing code together from different places.
This article gives you a quick way of handling the JWT and how to decode it, so you can verify the user on the server. I used Ruby on Rails on our server but the method should be same.
Here is a few notes that I thought was useful
- The JWT expires after 10 minutes
- After validation, you should have your own authenticating mechanism — for example a token that the user uses on all the other requests for your API
- The JWT only contains the userIdentity and email (no full name for example)
- When creating a user on your server, you must use userIdentity as their primary/look-up key, because the email will change depending on user settings
How to get the userIdentity and JWT ?
This one you need to get on the device. It’s pretty simple and straightforward. You just need to enable “Apple Sign In” in Project -> Signing & Capabilities -> Add “Sign in With Apple”.
Then you can start the sign in session using the code below
That’s it. The reason why i’am sending the users full name to our servers is because the JWT does not contain it, it only contains the email of the user and for us to create a new user on our server we need both email and name. This could be different in your case.
Handling the JWT on the server side
To decode the JWT you will need to get a public key from Apple. This public key is hosted on https://appleid.apple.com/auth/keys but in a format called JWK. (JSON Web Key).
Our script will download the key and use it to decode the JWT, then compare the information in the JWT with the userIdentity which is also sent from the client.
The gem I use for JWK/JWT is simply called ‘jwt’. Add it to your bundle and you should be good to.