2

I'm using AppSync with IAM auth with a DynamoDB resolver and Cognito. I'm trying to do the following.

{
    "version": "2017-02-28",
    "operation": "GetItem",
    "key": {
        "userId": $util.dynamodb.toDynamoDBJson($ctx.identity.username)
    }
}

$ctx.identity.username is supposed to contain userId generated by Cognito and I'm trying to use it to fetch current user data.

Client side, I'm using AWS Amplify that tells me I'm currently logged:

this.amplifyService.authStateChange$.subscribe(authState => {
  if (authState.state === 'signedIn') {
    this.getUserLogged().toPromise();
    this._isAuthenticated.next(true);
  }
});

getUserLogged is the Apollo query that is supposed to returns user data.

What I've tried:

  • If I leave it like this, getUserLogged returns null.
  • If I replace in the resolver $util.dynamodb.toDynamoDBJson($ctx.identity.username) with a known userId like this $util.dynamodb.toDynamoDBJson("b1ad0902-2b70-4abd-9acf-e85b62d06fa8"): It works! I get this user data.
  • I tried to use the test tool in the resolver page but it only gives fake data so I can't rely on this.

Did I make a mistake? To me everything looks good but I guess I'm missing something?

Can I clearly see what $ctx.identity contains?

Tom
  • 785
  • 10
  • 26

1 Answers1

3

You'll want to use $ctx.identity.cognitoIdentityId to identify Cognito IAM users: https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference.html#aws-appsync-resolver-context-reference-identity

You could see the contents of $ctx.identity by creating a Lambda resolver and logging the event or by creating a local resolver and returning the input that the mapping template receives: https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-local-resolvers.html

My cognitoIdentityId looks like this: eu-west-1:27ca1e79-a238-4085-9099-9f1570cd5fcf

Lindlof
  • 2,152
  • 2
  • 17
  • 26
  • Alright. I can try that but are you sure that `$ctx.identity.cognitoIdentityId` is not linked to devices? What if this user comes with another device. Will he have the same value in `$ctx.identity.cognitoIdentityId`? What if he wants to loggin with `Twitter` latter. Will there still be the same value in `$ctx.identity.cognitoIdentityId`? Thank you for your help @mikuz. – Tom Jul 08 '18 at 10:19
  • 1
    The context reference recommends using `cognitoIdentityId` for identifying users from Cognito Federeated Identities. I see no evidence of it binding to a device but you can test that hypothesis. Connecting Twitter login to User Pools login? I don't think that's something that Federated Identities supports. Certainly you can develop a system to connect the logins from the two providers (you'll probably need to use Lambda resolvers for that). – Lindlof Jul 08 '18 at 10:35
  • It seems that `cognitoIdentityId ` is not available in `Cognito` triggers. I'm currently using a trigger to store an uniq userId generated by Cognito. An Id I can use in my resolvers. I'm lost. – Tom Jul 08 '18 at 10:56
  • This answer should help you with using the Cognito UserPools user and Federated Identities IAM user together https://stackoverflow.com/a/50109477/1207523 – Lindlof Jul 08 '18 at 11:00
  • So I have to use a `Lambda` function to get the author from every single query made? – Tom Jul 08 '18 at 11:11
  • Not sure what you mean. In that answer I describe a system where all user data (UserPool and Federated Identities) are stored in a DynamoDB item during login. In GraphQL you can retrieve that data in any query by having a DynamoDB resolver on `author` field. – Lindlof Jul 08 '18 at 11:19
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/174590/discussion-between-tom-and-mikuz). – Tom Jul 08 '18 at 11:20