I’m trying to set up a basic website (serverless on AWS) that would allow visitors to login with Google and/or Facebook. Currently I’m planning to use S3, Cognito with Federated Identities, API Gateway, Lambda (NodeJS), with DynamoDB. The client app will be using Angular.
I have the social login with Google and Facebook working, and currently I am inserting a row in a “users” table when a user logs in the first time that includes the cognitoId, name, profile picture URL, etc.
I also figure it would be a good design to store the user’s information with their email address as the key, instead of something like the cognitoId so that the user can login using different Providers and see the same data. So I need to know the authenticated user’s email address, but I figure it should come from Cognito and not straight from the user (since the client app shouldn’t be trusted).
I believe that Cognito is storing the user’s email address because I have enabled that field as required int the User Pool.
The issue I’m having is that I cannot find any information about how to get the user’s email address from Cognito.
The closest that I’ve come is this post, but I can’t find the access token anywhere: How to get user attributes (username, email, etc.) using cognito identity id
This post indicates that I may be able to use GetUser, but I again don’t know where the AccessToken comes from: creating user using AWS cognito identity
If I do need to use GetUser and the AccessToken, where does it come from, and how do I generate it? Does it come from the client, or can I get it in Lambda using AWS.config.credentials?
I’ve been trying to figure this out for a while now and I’m feeling like I’m missing something really simple!
3
Answers
To get the email, you have to request it to the identity provider (facebook, google, user pool).
To get the email from the user pool you have to do something like:
Cognito Identity doesn’t save the emails.
Firstly, go into Cognito Identity provider (in the Cognito console) and make sure your provider “Authorize Scope” is suitable. For example if you clicked on the Google provider your Authorize scope might be “profile email openid”. The scope will vary by provider, but whatever scope you are using, it must provide access to the users email.
When your user logs in with an external identity provider (lets say Facebook), Cognito negotiates with Facebook and then calls your Callback URL, which is set in the ‘App Client Settings’ part of the Cognito console. That Callback contains a parameter called ‘code’ – the parameter is set in the URL of the Callback made my Cognito. The code is an OAuth token.
Now you have an OAuth token in your client you need to POST that to the AWS Token Endpoint. The token endpoint returns three new tokens in the response; a JWT ID Token, a JWT Access Token and a refresh token. Take the “id_token” attribute from the endpoint response. Parse that id_token as a json string, and take the ’email’ element. Now you should have the users email address.
Here is my working example in Java. This is a servlet that gets called by the Cognito Callback.
You also need to add Attribute mappings in your user pool. Check if you have forgotten to add the mappings. You can find “attribute mappings” tab under “federation” inside your User Pool settings