aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.44k stars 2.13k forks source link

signInWithApple does not import firstName and lastName attribute on first sign in #10182

Open arceusVen1 opened 2 years ago

arceusVen1 commented 2 years ago

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

Authentication

Amplify Categories

auth

Environment information

``` # Put output below this line ```

Describe the bug

Hi,

Before you ask, I've seen previous closed issues on this subject but the accepted answers did not help. I want to import first name and last name attribute for a user that Sign In with Apple for the first time to pre-fill information inputs. Despite my best efforts, I can't manage to make this happen. I've made sure to delete my test user from pool and "stop using apple sign for service" for my app via Apple ID dashboard for every tests, I've tried mapping to standard attributes and custom attributes as well to see any difference, I've tried to go via hosted UI to get around any implementation problem. All of this gets the same result I can sign in without any problem but cannot get the attributes I am looking for. Can anybody think of something for my problem, I've even tried to log pre sign up event via lambda to see if something is up but don't see any issue, just not the attributes I am looking for. Perhaps it's from my pool config, I'll attach some screenshot so maybe someone sees something I don't.

Thank you all for your help !

Capture d’écran 2022-08-09 à 15 39 22 Capture d’écran 2022-08-09 à 15 39 44 Capture d’écran 2022-08-09 à 15 40 41 Capture d’écran 2022-08-09 à 15 53 33

PreSignUp event logs :

{  
  version: '1',  
  region: 'eu-central-1',  
  userPoolId: 'MY_POOL_ID',  
  userName: 'signinwithapple_001324.e1a3f6f0f6264f43b3ae0189a97ca8f2.1457',  
  callerContext: {    
    awsSdkVersion: 'aws-sdk-unknown-unknown',    
   clientId: 'MY_CLIENT_ID'  
  },  
  triggerSource: 'PreSignUp_ExternalProvider',  
  request: {    
    userAttributes: {      
      email_verified: 'false',     
      'cognito:email_alias': '',     
      'cognito:phone_number_alias': '',      
       email: 'USER_TEST_MAIL'    
    },    
   validationData: {}  
  },  
  response: {    
    autoConfirmUser: false,    
    autoVerifyEmail: false,    
   autoVerifyPhone: false  
  }
}

Expected behavior

I want my user to have Given Name and Family Name properly mapped to firstName and lastName for a first time apple sign in

Reproduction steps

Delete user from pool, stop using Apple ID for service via apple dashboard and sign in again on my app. Sign in is successful but attributes are not mapped

Code Snippet

<button onClick={() => Auth.federatedSignIn({provider: 'SignInWithApple'})} type="button">
     sign up with apple
</button>

Log output

``` // Put your logs below this line ```

aws-exports.js

const config = {
    Auth: {
        userPoolId: MY_POOL_ID,
       userPoolWebClientId: MY_WEB_CLIENT_ID,
       mandatorySignIn: false,
       authenticationFlowType: 'USER_SRP_AUTH',
       oauth: {
            domain: 'MY_DOMAIN.eu-central-1.amazoncognito.com',
            scope: ['phone', 'email', 'profile', 'openid', 'aws.cognito.signin.user.admin'],
            redirectSignIn: config.oauthRedirect,
            redirectSignOut: config.oauthRedirect,
            responseType: 'code' 
        }
    }
}

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

eltaf-buckitapp commented 2 years ago

Facing the same issue while having the exact above configuration as @arceusVen1 mentioned.

arceusVen1 commented 2 years ago

@eltaf-buckitapp Have you found any solution for the problem. It's reassuring to know I am not alone in this situation but I still cannot make it work unfortunately. Also it appears that the problem is not amplify js related because I am facing the same issue for our flutter mobile app and it blocks iOS deployment validation from Apple. :/

eltaf-buckitapp commented 2 years ago

@eltaf-buckitapp Have you found any solution for the problem. It's reassuring to know I am not alone in this situation but I still cannot make it work unfortunately. Also it appears that the problem is not amplify js related because I am facing the same issue for our flutter mobile app and it blocks iOS deployment validation from Apple. :/

No unfortunately I have not found any solution, since I am just using for web only, I force user to add names manually after cognito account creation.

nadetastic commented 2 years ago

Hi @arceusVen1 👋,

Thank you for raising this issue. I can confirm that I'm able to consistently reproduce this on my end as well. From what I've gathered so far, it appears that the Name attributes are either not returned from Apple, or there's an issue with the attributes mapped on Cognito's end. Also as @eltaf-buckitapp has mentioned, this issues doesn't appear to be specific to Amplify JS.

I'm taking a further look into this and will update you once I have additional info.

nadetastic commented 2 years ago

@arceusVen1 @eltaf-buckitapp After discussing with the Cognito team, it appears that this is a limitation from Apple. At this time, Apple does not include the First and Last name in the response after completing SignInWithApple.

As mentioned before, this is a limitation on Cognito and not Amplify library, but as a work around you can add attributes to after sign up as described here.

arceusVen1 commented 2 years ago

@nadetastic Thank you very much for the investigation. Very interesting response but I am surprised as well. We have been stuck with Apple validation when trying to deploy our mobile app because the Sign In with Apple did not import names attributes and therefore did not respect their 4.0 guidelines. But now it turns out it's their fault for not providing them anymore haha. We found a tricky but functional workaround in the meantime but thank you anyway. I appreciate the time spent on this issue. I will close it then.

AlanAevo commented 1 year ago

Hello @arceusVen1, We are having the exact same problemas with Apple's 4.0 guidelines. It appears they do send the name and lastName in the first login, but Cognito doesn't seem to be mapping the attributes. Can you please tell us what workaround you're using to get over this issue?

arceusVen1 commented 1 year ago

hello @AlanAevo. Humm it's sad if it's still not working. Unfortunately I am not sure my workaround can apply to you. We are a bidding service company so later down our process we need to verify ID of our users using a third party that returns user's information including their first name and last name coming from their id documents. So whenever we have an apple sign in user we just don't ask for first name and last name and wait until they validate their ID later if they wish to bid. The data returned from our third party usually overrides anything already registered so it wasn't a big deal anyway. We just have a few users in our database with no last name and first name but they can't do much unless they check their ID so the deal was acceptable and after discussing with apple support this process does respect their 4.0 guidelines. Sorry I can't be of much help but perhaps it will inspire you in some ways.

AlanAevo commented 1 year ago

I see @arceusVen1, thank you for your swift reply. This method indeed is specific to your use case. We will have to bring this up to the Cognito team and search for a workaround in the meantime. Both the email and the user name are sent in the same object by the apple request, but only the email gets mapped it seems

arceusVen1 commented 1 year ago

No worries @AlanAevo . If you manage to get answers from cognito team, mention it here if you can and it's useful I would be interested to know more and I am sure it will help others too. We can't be the only ones to have faced this problem.

garethrhughes commented 1 year ago

I'm having the same issue, has there been any progress on this?

trobert2 commented 1 year ago

is sending the name attribute dependent on anything the user does in their apple ID configuration? I have some accounts that do indeed send the name and some that don't. I just can't figure out when this is the case and why. When I try to sign in with apple, on both accounts (the one that does have the name in the user pool and the one that does not) I get a chance to edit the name during the process.

AlanAevo commented 1 year ago

@trobert2 . Our team observed that the reason the attribute sometimes gets mapped is because of the presence of the attribute middleName in the object apple returns to cognito (together with firstName and lastName) In some cases apple doesn't send this parameter and the mapping happens as expected, but if the parameter is included then it seems the entire name get's discarded. Unfortunately we haven't figured it out why sometimes apple sends or doesn't send this parameter, in some accounts we tested they send middleName as an empty sting even if the user never added a middle name, breaking the mapping Since it looks like a cognito bug, for now our team had to exclude the name mapping from iOS devices

kazimhomayee commented 1 year ago

I have been facing the same issue.

If the middle name exists on icloud account, given name / family name / middle name is missing from congnito user otherwise we're getting given name / family name to congnito user.

Mik77o commented 1 year ago

I have a similar problem. After creating an account via Apple, I get the first name and last name in one attribute: family_name.

walterholohan commented 1 year ago

Does anyone have a workaround for this? At the moment we have the below mappings but we get back no name for our users. Can we use different variable other than firstName or lastName e.g. first_name

image
nadetastic commented 1 year ago

Hi @walterholohan unfortunately I am unable to provide a work around at this time, however we are actively investigating this issue with the Cognito team, and will provide an update as soon.

Weixuanf commented 1 year ago

Why I can't get any firstName, lastName at all even the middle name doesn't exist on cloud account?

I have been facing the same issue.

If the middle name exists on icloud account, given name / family name / middle name is missing from congnito user otherwise we're getting given name / family name to congnito user.

MensurRasic commented 1 year ago

+1 : Facing the exact same issue on our side, hope it gets fixed soon! :)

dzaiats commented 1 year ago

Just got a rejection from Apple due to this bug.

vbadri commented 1 year ago

We also got a rejection from Apple due to this bug

joeig commented 1 year ago

I noticed that the attributes are actually mapped correctly after you signed in with Apple for the first time. However, all subsequent calls to SignInWithApple - including the call that is triggered to get a JWT - won't contain the requested attributes, hence they are removed by Cognito.

There is an answer in the Apple Developer Forums which confirms my observation.

Assuming that Apple won't change their workflow, there should be two options:

  1. Wait for the Service Team at AWS to handle Apple's workflow. This would probably have the biggest positive impact for all Cognito users, since the attribute mapping is just not working right now without obvious reason.
  2. Untested workaround: Implement a Lambda trigger that puts the relevant attributes in a DynamoDB table right after the initial sign in but before the first JWT was issued. PostConfirmation should be the right choice. Whenever a JWT is being issued, use the PreTokenGeneration trigger to get the attributes from DynamoDB and add them to the token. I haven't tested this workaround specifically with SignInWithApple, but I'd be happy if somebody confirms if it works.

After all it's still unclear to me how SignInWithApple behaves when an attribute changes on Apple side. I assume they add the changed attribute one time to the first response after the attribute was changed.

hanna-becker commented 11 months ago

+1

taylorbyks commented 11 months ago

I managed to find a solution:

1 - Make sure you checked "Name" on Authorized scopes in your SignInWithApple (user pools -> identity providers -> SignInWithApple)

Captura de Tela 2023-12-18 às 16 33 32

2 - After that you must map the fields:

Captura de Tela 2023-12-18 às 16 34 01
suupham2506 commented 9 months ago

I got the same issue, but finally I found out the solution for this issue.

It currently works for me now. Share this for everyone. ✌️

Give me a 👍 if you find it helpful. Thanks

spap975 commented 8 months ago

Has this issue been resolved yet? Kinda crazy to add Apple auth in your provided services but not provide the necessary functionality to have it accepted by Apple.

alexomon018 commented 5 months ago

Same issue here, my app can't get approved because of this.

hcac10 commented 5 months ago

Has this issue been resolved yet? Kinda crazy to add Apple auth in your provided services but not provide the necessary functionality to have it accepted by Apple.

+1 on this. Sign in With Apple is a pretty important aspect for production grade iOS apps. If Cognito/Amplify is unable to fully integrate with it, it could possibly alienate customers from Amplify down the road.

loera140 commented 5 months ago

Not saying this is the solution but this is just what worked in my case.

I was able to sign in via Apple SignIn but was not recieving the lastName and firstName. I was testing multiple times and was sure my attribute mapping was correct. I deleted the user from cognito multiple times to trigger a "first sign in" and still could not get the name mapped correctly.

Finally,

  1. I logged into https://appleid.apple.com/sign-in with the apple credentials I was using to test
  2. Clicked on "Sign-In and Security"
  3. Then selected "Sign In with Apple"
  4. and removed the App which I was testing
  5. once agan deleted the user from Cognito
  6. and this trigger the full sign in flow from the Apple UI which asks if you'd like to share/hide your email
  7. on completion the users lastName and firstName were mapped to given_name and family_name as expected
alexomon018 commented 5 months ago

@loera140 Thanks for the update! I will give this a try for sure later on. So, it is working for users who are signing in for the first time and choose to share their email, I suppose?

alexomon018 commented 5 months ago

@loera140 Tested and it works. Thanks again for this!

surajbarailee commented 5 months ago

@alexomon018 What did you find? Is this statement correct? : If user choose to hide email, we can't get the names. There are no related attributes. And if they choose to share, the attributes map correctly.

gajojr commented 4 months ago

Here are the steps to make this work: Before I describe the steps we need to find given_name and family_name, that is equivalent to firstname and lastname perspectively since apple doesn't call them that way. Also for security reasons apple only allows fetching these attributes on the first app sign up and not for every sign in, if you need to access them again you'll need to repeat the whole process.

  1. Delete the app from the list of sign ins on your iPhone ( Password & Security -> Sign In & Security -> Sign in with Apple -> App that you want to delete sign in for)
    • sometimes you'll see this app is not removed but no worries, that is just a bug that still allows you to continue with this process (looks like apple didn't delete it but it did)
  2. Delete user from amplify
  3. Add name to access scope (not just email) on sign in with apple settings in your user pool -> SignInWithApple

Screenshot 2024-07-07 at 18 12 31 (2)

  1. map the prop you want to given_name (firstname) and family_name (lastname)

    • mapping sometimes doesn't work, but you'll get given_name and family_name in that case and not the props you chose Screenshot 2024-07-07 at 18 15 35 (2)
  2. Access the props with code:

const currentUser = await Auth.currentAuthenticatedUser();

const attributes = await Auth.userAttributes(currentUser);

/* Attributes are in this format:
[
   {
      "Name":"sub",
      "Value":"..."
   },
   {
      "Name":"identities",
      "Value":"[{\"userId\":\"...\",\"providerName\":\"SignInWithApple\",\"providerType\":\"SignInWithApple\",\"issuer\":null,\"primary\":true,\"dateCreated\":...}]"
   },
   {
      "Name":"email_verified",
      "Value":"false"
   },
   {
      "Name":"given_name",
      "Value":"..."
   },
   {
      "Name":"family_name",
      "Value":"..."
   },
   {
      "Name":"email",
      "Value":"..."
   }
]  */
  1. When you click sign in with apple instead of doing Face ID, click chose other account and then use same email and password you wanted since this is needed to trigger the pop up where it asks to show or hide an email. Click show email since hiding an email won't be able to get given_name (firstname) and family_name (lastname) property.
hcac10 commented 3 months ago

Hi @gajojr thanks for sharing! I was initially really excited because when I tried this as first and last name started importing correctly. However, after generating a production build using Expo/EAS, signing up with apple on real iOS devices defaults to a version where the name is not imported. Have you / anyone else encountered this discrepancy in behavior ?

gajojr commented 3 months ago

@hcac10 If you previously had the build of this app on the device you need to repeat the whole process there as well, like you did on the simulator

manibha-jain commented 3 months ago

Hi all, Facing issue with apple, where I only get email and user id data from the decoded ID token(JWT), and do not get user's first and last name. But I when get the ID token from apple in web/mobile implementation, I get user's first name and last name in the response only for the first time. And then It also gets vanish from the ID token response. Any idea what to do here?.

hcac10 commented 2 months ago

Hi @gajojr thanks for sharing! I was initially really excited because when I tried this as first and last name started importing correctly. However, after generating a production build using Expo/EAS, signing up with apple on real iOS devices defaults to a version where the name is not imported. Have you / anyone else encountered this discrepancy in behavior ?

Following up on this, the issue was not related to simulator versus the real device. Rather, if you follow the steps, it works the first time you sign in. If you delete the account from Amplify, and try and sign up with the same apple ID, it will not import the names again.