How the server can get the user's email reliably through Sign in with Apple?

TL;DR, how is the server-side of the app intended to obtain access to the name and
email of a user after they have completed the Sign in with Apple flow?
We note that the email is present in a signed form in the `id_token` returned by the https://appleid.apple.com/auth/token endpoint [1]. However this appears to be only available to the server the first time a user logs in and not on subsequent login attempts. ([1] https://developer.apple.com/documentation/signinwithapplerestapi/generate_and_validate_tokens)


  • In the case that the app failed to send the token to the server during the initial authorisation for some reasons(e.g. network connection failure or battery down), the server can never ever know the user's name/email through Sign in with Apple. Is it correct?
  • If so, which means,
    • it doesn't really matter what the user has opted for, share email or use private email,
    • it also doesn't matter how we store the information and link to the user id,
    • cause the server never had the chance to store the user information(name & email) in the first place
    • however weirdly the client does get the email address on subsequent attempts


Looking for the guidance: How the server of the app intended to get the user's email through Sign in with Apple in a reliable way?

Replies

It looks to be by design, for privacy & security reasons. You have a 600 second window on the identity token to cache it on the device and later push it up. Then subsequently cross-check the token with the identifier thats in that jwt's sub. But the flow is similar to what you'd do with Storekit verifications.


Otherwise, there doesn't look to be an easy way for the user to flush the authorization device-side.

Thanks for the answer.


It does make a lot of sense. But still couldn't solve the following case:


Scenario: What if during the initial authorization, the "client -> apple" request succeeded but "apple -> client" failed, meaning the initial token with email has been issued, but the client didn't get a chance to have it at the first place. Then nothing to cache and send back to our own server.


Any idea?

In advance, many thanks!

This is exactly an issue we're running into as well. Basically subsequent calls would not give you the email anymore and there's no way of retrieving that info if there's a failure on our server end during the callback.


Yes apps can cache that info but what about scenarios like a web browser signing in with incognito mode turned on? We need to be able to retrieve this info again and not just the first time only.


Apple please respond

So from a local perspective with your scenario - client->apple and apple->client are the same. There's no client token exchange to be done, so the auth and token flow occur in a single flow. The logic is fail-close, either the user auths against apple and gets an initial token or the auth fails and no initial token. Because of that aspect, you just need to implemnt logic to store and cache the identity token as soon as the auth flow finishes. I don't see a way for the flow to auth a client and *not* respond with the identity token.


With the identity token cached, have the user do a subsequent auth against your server wherein, presumably you've set up the server-side for Sign in with Apple, you can validate the identity of the user. Afterwards, it's just between your server and apple at that point.


Apple can probably solve this by giving you a 1 hour window after first auth to perform a re-auth to retrieve the email address. At the same time, if all this is intentional then I have to give praise. Way too many people are collecting user PII unnecessarily and abusing the user's right to privacy.