Can't retrieve name and email from Sign In flow

Hi,


We've just implemented Apple Sign In according to the documentation (https://developer.apple.com/documentation/signinwithapplerestapi), the login is working fine, but there is no way to get the email from the token. We tried a lot of different scopes, and while only a few seem to be valid (name, email, openid), they don't seem to change anything to the response of the token. The only field that's in there is "id_token", and the only useful field in the "id_token" is "sub", which seems to be a unqiue identifier. Is there a way to retrieve the email address?


Thanks!

Answered by DTS Engineer in 413866022

To request user information in the `id_token` (assuming you are requesting via the `/auth/authorize` REST API), you'll need to include the `scope` query parameter, which supports the values—`name` and `email`. You can request one, both, or none.


Note: Use space separation and percent-encoding for multiple scopes; for example, `"scope=name%20email"`.


For additional information about preparing the authorization request, please see the following documentation—


https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms

Same issue here, important how to fix this. Some technical details:


The flow is working correctly as described in https://developer.apple.com/documentation/signinwithapplerestapi

As in the presentation https://developer.apple.com/videos/play/wwdc2019/706


Request: https://appleid.apple.com/auth/authorize?response_type=code+id_token&client_id=www.example.com&redirect_uri=https%3A%2F%2Fwww.example.com%2Fhandle%2Fapple%2F&state=acfb01022b&scope=email


The scope has explicitly asked for email.


After a succesfull login: Example Token request: https://appleid.apple.com/auth/token?code=CODE_FROM_APPLEID&redirect_uri=https://www.example.com/handle/&client_id=www.example.com&client_secret=DONT_TELL


The validation response: https://appleid.apple.com/auth/token Has the following response



[access_token] => a2293d83289aa41f7ad22de6844511826.0.mzuq.oCJsXOEXZQX1v8NQCQOy0g

[token_type] => Bearer

[expires_in] => 3600

[refresh_token] =>

[id_token] => REeyJraWQiOiJBSURPUEsxIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczpcL1wvYXBwbGVpZC5hcHBsZS5jb20iLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJleHAiOjE1NjE0OTA2MTUsImlhdCI6MTU2MTUzMzU4OCwic3ViIjoiMDAwMTMyLmMzTWlPaUpvZEhSd2N6b3ZMMkZ3Y0d4bGFXUWFzZHNhLjg5MTQiLCJhdF9oYXNoIjoiQnBiVmVmTm5waVBUY1BzcWt3VEppZyIsImVtYWlsX2R1bW15IjoiZXhhbXBsZUBwcml2YXRlcmVsYXkuYXBwbGVpZC5jb20ifQ==.SyCF8jT50FHALit-u9H_TyzPikirYnDq1RiDT3ennHQrNl0UcRE4bDmVM1qlG2cfHPH5OtpyQZIjGi_r9v7ZoN2EfyDGlg08yEWGwwCNlrCkcHcA9gjNN2RYmT4Yt3toRLgnwSDyzHOP6FS7I1kzwcdZmJTuGrYPThxe80F6rQABUWUBDAl2KgP7ujt1j8H3LrfV0r3RKTHA7azWWu9rVAFrx1_IeRk-ASDW0OPrqDJoF8YdZF1Da4-br-gTOt_LJhZFhuPh1WDgZj6AAcytTrSL4AhW2BrN_U0bMw47nw7k9OZbcbDNb-j3hEAkQdvZYEBHIRtEMxrzTAgs7oxbtg



[iss] => https://appleid.apple.com

[aud] => www.example.com [exp] => 1560776678

[iat] => 1560776078

[sub] => 000132.c3MiOiJodHRwczovL2FwcGxlaWQasdsa.8914

[at_hash] => SrJXsKX1f4FpGPFmiUPzUQ


In the response there is no (anonymous) email address.

This will be enhanced soon, and the email or anoymous email will be in id_token.

The change to include the email address in the ID token is currently being worked on and will be available soon.


Currently the email address is provided to the application front-end through the post to the redirect uri.

"Currently the email address is provided to the application front-end through the post to the redirect uri"

but in post repose to redirect uri we are getting only state, id_token and code. How can i get the email address?

This. We only get state and code in the redirect uri, no email address.

We only support response_mode "form_post". we will make form_post as default and remove redirect. In the meantime please add &response_mode =form_post in the request


ex.


https://appleid.apple.com/auth/authorize?response_mode=form_post&....

But... Why? form_post is not really common. It also makes handling authentication hard when using Javascript apps like Angular. This will just be another hassle for us to implement this, now we have to implement a method serverside to transform the form_post into a redirect again.

Nice! For our release planning, is a release date and field name of the email in the id_token known at your side?

Saw this for the first time today, there are now four items in the posted form data on successful login: state, code, id_token, and *user*. User has firstName, lastName, and email in a json blob.


Should we be concerned about replay attacks, since the user info is unsigned? In other words, if a nefarious actor replays a previous post but changes the "user" to something else, is that detectable?

This is a nice solution for the embeded Apple Web JS https://developer.apple.com/documentation/signinwithapplejs/configuring_your_webpage_for_sign_in_with_apple


But not for the OAUTH2 implementation.


We should indeed verify this data. Perhaps the best solution is that the validation response: https://appleid.apple.com/auth/token should have this (encode base64) user data (email and name) without the response_mode=form_post variable (also support get responses, see comment jeroen klippa).


Example:

[access_token] => a2293d83289aa41f7ad22de6844511826.0.mzuq.oCJsXOEXZQX1v8NQCQOy0g

[token_type] => Bearer

[expires_in] => 3600

[refresh_token] =>

[id_token] => REeyJraWQiOiJBSURPUEsxIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczpcL1wvYXBwbGVpZC5hcHBsZS5jb20iLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJleHAiOjE1NjE0OTA2MTUsImlhdCI6MTU2MTUzMzU4OCwic3ViIjoiMDAwMTMyLmMzTWlPaUpvZEhSd2N6b3ZMMkZ3Y0d4bGFXUWFzZHNhLjg5MTQiLCJhdF9oYXNoIjoiQnBiVmVmTm5waVBUY1BzcWt3VEppZyIsImVtYWlsX2R1bW15IjoiZXhhbXBsZUBwcml2YXRlcmVsYXkuYXBwbGVpZC5jb20ifQ==.SyCF8jT50FHALit-u9H_TyzPikirYnDq1RiDT3ennHQrNl0UcRE4bDmVM1qlG2cfHPH5OtpyQZIjGi_r9v7ZoN2EfyDGlg08yEWGwwCNlrCkcHcA9gjNN2RYmT4Yt3toRLgnwSDyzHOP6FS7I1kzwcdZmJTuGrYPThxe80F6rQABUWUBDAl2KgP7ujt1j8H3LrfV0r3RKTHA7azWWu9rVAFrx1_IeRk-ASDW0OPrqDJoF8YdZF1Da4-br-gTOt_LJhZFhuPh1WDgZj6AAcytTrSL4AhW2BrN_U0bMw47nw7k9OZbcbDNb-j3hEAkQdvZYEBHIRtEMxrzTAgs7oxbtg


[iss] => https://appleid.apple.com

[aud] => www.example.com [exp] => 1560776678

[iat] => 1560776078

[sub] => 000132.c3MiOiJodHRwczovL2FwcGxlaWQasdsa.8914

[at_hash] => SrJXsKX1f4FpGPFmiUPzUQ


[user] => {"name":{"firstName":"Jane","middleName":"","":"Doe"},"email":"j123easj2@privaterelay.appleid.com"} (ENCODE BASE64)


Is this a good solution for the OAUTH2 implementation?

I think the idea of including user name/email in the JWT as Aniwat mentioned above would get us out of the woods

The email should be in included in ID token now. Please try.

Thanks for this update! Also nice that the form_post is not required. The only note is that name is not in the response. Also the email/name field is should be always in the ID token (at this moment only with the startup). I'll make a workaround for this, but it is not the "standard"-way in the oauth procedure.

@tdh42 where do you see that form_post is not required?

@tsombrero


Used the following example (in https://appleid.apple.com/account/manage delete your app, you get the email only the first time)


https://appleid.apple.com/auth/authorize?response_type=code+id_token&client_id=www.example.com&redirect_uri=https%3A%2F%2Fwww.example.com%2Fsocial%2Fapple&state=dedfdd8816&scope=email


It is a GET response, then the token validation as described above with the field email in the id_token


Use the sub-field as identifier

Thanks! My only concern is that the way things are changing it doesn't feel safe to code against a GET flow until it is documented as supported.


@Apple can we please document and support the GET redirect-flow to help with Android clients and others who don't handle POSTs well?

Do you plan on adding the name to the id token? It makes it easier to grab it alongside eveything else here.

Could you please add the name to the id_token? It's also really annoying that you only get this information the first time someone goes through the flow, is it possible to always add this information?

According to @Natthakorn123 using form_post will be required later on. I also don't feel quite conviced that the way we are developing our flow now will work when it's finally released. We can't implement form_post with a major overhaul in our authentication implementation and with some middleware API endpoint that handles redirecting between Apple and our Angular app.

I'm also having issues with exchanging the code from the mobile SDK serverside.

When I try to do an oAuth2 exchange with the authorizationCode from the mobile SDK, the server returns the HTTP 400 error "{"error":"invalid_grant"}"

what are your request details? grant_type='authorization_code' should be - is it?

@tdh42 how did you get the user json in response ? I implemented both "Sign in with Apple REST API" and "Sign in with Apple JS" and in both cases I didnt get the user json in response, I am sure i have implemented them correctly as I am getting response from Apple but no user info in both cases, in both cases I am getting following response :-


Sign in with Apple JS ==> { "code" : "...." , "state" : ".... ", "id_token" : "...." }

Sign in with Apple REST API ==> { "access_token" : "...." , "token_type" : "....", "bearer" : "......", "expires_in" : "......", "refresh_token" : ".....", "id_token" : "......." }


NOTE :-

1) I have also decoded and checked id_token there is no user info in there

2) "......" means some data

@aks_64

You'll only get the emailaddress once from the token validation: https://appleid.apple.com/auth/token in the id_token


You should save the email with the sub (identifier).

All I get now is {"iss":"https://appleid.apple.com","aud":"*****","exp":1566915927,"iat":1566915327,"sub":"*****","at_hash":"LO4e93EaBSHzBZ3RajVYcA","auth_time":1566915325}, no email info, though my authUrl looks like https://appleid.apple.com/auth/authorize?response_type=code&client_id=****&redirect_uri=****&state=****&scope=name%20email&response_mode=form_post


where can I get email address?

Can't retrieve name and email from Sign In flow
 
 
Q