3

I was happily using Cognito Sync with my pre-release app (iOS/Objective-C), with Facebook login. However, upon submitting for Apple App Store review, I was asked to remove Facebook login. I thought it would be straightforward - just changed the unauth role policies to match the auth user and bypassed anything to do with Facebook authentication.

However, now I am finding that identityId is changing between sessions. It is behaving like a session ID. This is a major headache because my app uses identityId as the hash key in DynamoDB. So, for example, a DynamoDB search for recent activities by current user shows only the current session's history, not ALL history as intended.

I was using the sample app's code to obtain identityId - it seems to be getting assigned correctly. Based on the sample's AWSIdentityManager.m, following is part of the AppDelegate.m inside didFinishLaunchingWithOptions:

AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AMAZON_COGNITO_REGION
                                                                                                identityPoolId:AMAZON_COGNITO_IDENTITY_POOL_ID];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AMAZON_COGNITO_REGION
                                                                     credentialsProvider:credentialsProvider];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;

[[credentialsProvider getIdentityId] continueWithBlock:^id(AWSTask *task) {
    if (task.error) {
        NSLog(@"Error: Could not obtain identity id: %@", task.error);
    }
    else {
        // the task result will contain the identity id
        NSString *cognitoId = task.result;
        NSLog(@"Got the identity ID as %@", cognitoId);
        // Don't change the ID
        NSString *oldId = [[NSUserDefaults standardUserDefaults] objectForKey:NSUD_COGNITO_ID];
        if (!oldId) {
            [[NSUserDefaults standardUserDefaults] setObject:cognitoId forKey:NSUD_COGNITO_ID];
            [[NSUserDefaults standardUserDefaults] synchronize];
        } else {
            NSLog(@"Old = %@, New = %@, Keeping old", oldId, cognitoId);
        }
    }
    return nil;
}];

I keep getting the message that old and new identities are not the same. Also, when I check in Cognito Sync, the old identities can no longer be found.

Now that there is no Facebook SignIn provider in use, how do I ensure that the identityId does not change across sessions etc? Can someone shed a light on why this is changing? I have confirmed that I am not clearing the keychain anywhere in the code.

LNI
  • 2,935
  • 2
  • 21
  • 25
  • If it helps: The first few entries have "us-east-1:c5263844-7229-4e48-a203-f4c547871339" as the identityId, and subsequent entries have "us-east-1:86a69d0f-bb28-4acd-a229-9821d18e56ba" as the identityId. I checked in Cognito Identity Browser, and the first value does not exist in there. – LNI Jan 05 '16 at 20:34
  • I upgraded to 2.3.3 just now and am seeing a new message in the logs: "[AWSCognitoDataset synchronizeInternal:] | Conflict retries exhausted". Does that point to the potential cause? – LNI Jan 12 '16 at 17:29

2 Answers2

1

When using AWSCognitoCredentialsProvider the identityid is cached locally and will be retrieved on instantiation of the provider for re-use.

Possible solutions: (1) To get the identity id use "credentialsProvider.identityId" rather than "getIdentityId" (2) Make sure you are not calling clearCredentials or clearKeyChain when closing the application

Comments: Using unauth is fine, however if the user deletes their application or logs in from a different device there is no way to get the same identity again (as they are unauthenticated). If you need users to be able to access the same data across device/app installs you will need some sort of authentication

Mark Mercurio
  • 983
  • 6
  • 9
  • Thanks Mark! That was my understanding as well. I confirmed I am not calling clearCredentials or clearKeyChain anywhere in my code. Why did two different IDs get assigned? Is it possible for you to take a look at the two IDs (I noted them in the comment to original question above) and see if that gives you some insight as to the cause? Will there be any difference between credentialsProvider.identityId and [self.credentialsProvider getIdentityId] ? Won't they map to the same method call? I understand the unauth-related risk, will implement authenticated identity support in a later version. – LNI Jan 06 '16 at 01:22
  • Hi, thanks for checking that you do not call clearKeyChain and clearCredentials. It is unclear why you are getting two different IDs when only using unauthenticated, as these are cached here: https://github.com/aws/aws-sdk-ios/blob/master/AWSCore/Authentication/AWSCredentialsProvider.m#L351.... so couple of questions: (1) Has this been reproduced multiple times? (2) If you call credentialsProvider.identityId (rather than getIdentityId) does it return nil (indicating nothing is in the cache)? – Mark Mercurio Jan 07 '16 at 18:39
  • 1) Happens all the time. Here's the log from when I ran it just now: 2016-01-07 11:12:58.567 Scotch Aficionado[30819:4828008] Got the identity ID as us-east-1:f90736c9-d663-4fc3-9740-1b3c16b0d949 2016-01-07 11:12:58.567 Scotch Aficionado[30819:4828008] Old = us-east-1:32ed3260-140d-4249-b98d-933cd63e11fa, New = us-east-1:f90736c9-d663-4fc3-9740-1b3c16b0d949, Keeping old 2) I will check if credentialsProvider.identityId has not been changed. – LNI Jan 07 '16 at 19:13
  • Value returned by credentialsProvider.identityId is the same as task.result from [credentialsProvider getIdentityId], so yes the identityId is getting changed across runs. – LNI Jan 07 '16 at 19:16
  • Hi, if you could post a question (and reference this stack overflow post) in our forums - https://forums.aws.amazon.com/forum.jspa?forumID=173 it would be much appreciated and I can private message you there to discuss this further. – Mark Mercurio Jan 08 '16 at 00:05
  • I tried to, but I am getting an error "Your account is not ready for posting messages yet. Please try again later.". – LNI Jan 08 '16 at 01:13
  • Just posted in AWS forum: https://forums.aws.amazon.com/thread.jspa?messageID=695893򩹕 – LNI Jan 12 '16 at 17:37
1

For anyone else that may run into this situation:

The test phones (both iOS and Android) were using Facebook logins, when I changed the strategy to use unauth. It is important to remember (and not very well documented, in my opinion) that going from unauth to auth logins is a one-way street - you cannot go from authenticated user to unauth without resetting the IDs. So the issue I ran into seems to be unique to my situation (of attempting to go from auth to unauth).

LNI
  • 2,935
  • 2
  • 21
  • 25
  • So what would be the solution to go from auth to unauth? user can sign out and login again! – Bernard Nov 06 '16 at 12:29
  • @Bernard - I tried that and at least for the version I was using, the device did not "change hands" - ie the IDs did not reset to the new user. AWS may have fixed it now, have not tested it recently. Did you try logging out and logging in recently, and got the correct IDs back? – LNI Nov 11 '16 at 19:07
  • Yes I think AWS fixed it too. Also I made a mistake and have defined AWSCognitoCredentialsProvider twice. – Bernard Nov 13 '16 at 09:31