Reputation: 462
I'm using Appsync with the AWS_IAM authorization type. The identity of the user is provided in the $context.identity of the resolver:
{
"accountId": "123456789",
"cognitoIdentityAuthProvider": "\"cognito-idp.eu-west-1.amazonaws.com/eu-west-1_ABCDABCD\",\"cognito-idp.eu-west-1.amazonaws.com/eu-west-1_ABCDABCD:CognitoSignIn:SomeGuid\"",
"cognitoIdentityAuthType": "authenticated",
"cognitoIdentityId": "eu-west-1:SomeGuid",
"cognitoIdentityPoolId": "eu-west-1:SomeGuid",
"sourceIp": [
"123.456.78.9"
],
"userArn": "arn:aws:sts::123456789:assumed-role/some-role-name/CognitoIdentityCredentials",
"username": "ABCD1234:CognitoIdentityCredentials"
}
For now I'm using the cognitoIdentityId as the primary identifier of the user in my application. I'm happy to switch to accountId if needs be. My only requirement is that the primary identifier comes from identity object shown above, since I don't want to add additional request just to get the ID.
The problem: I have a workflow that requires a user to exist before the person logs in and uses the application. So I need to create the user and assign data to it. Somewhere down the line, the person may actually login for the first time and should have access to data that has been assigned to the user.
I can create the user in Cognito, but I can't seem to find a way to retrieve or generate the accountId or the cognitoIdentityId of the user that they would have when they eventually login to the application. Please help.
I figured out accountId has nothing to do with the user identity. It is the accountId of the AWS user that deployed the service (Appsync or Cognito, I don't know). So it is the same for all users.
So my question remains, how do I generate or retrieve the cognitoIdentityId of a user after creating it in the Cognito User Pool?
Upvotes: 0
Views: 842
Reputation: 462
I figured out a solution the essentially logs in as the user in order to get Cognito Identity ID:
import { config, CognitoIdentityServiceProvider, CognitoIdentity } from 'aws-sdk';
config.update({
region: process.env.REGION,
apiVersions: {
cognitoidentityserviceprovider: '2016-04-18',
cognitoidentity: '2014-06-30',
// other service API versions
}
});
export async function createUser(name: string, given_name: string, family_name: string, phone_number: string) {
var cognitoidentityserviceprovider = new CognitoIdentityServiceProvider();
var params = {
UserPoolId: process.env.USER_POOL_ID,
Username: phone_number, /* required */
MessageAction: "SUPPRESS",
UserAttributes: [
{
Name: 'name', /* required */
Value: name
},
{
Name: 'given_name', /* required */
Value: given_name
},
{
Name: 'family_name', /* required */
Value: family_name
},
{
Name: 'phone_number', /* required */
Value: phone_number
},
{
Name: "phone_number_verified",
Value: "true"
}
]
};
console.log("adminCreateUser")
let adminCreateUserResonse: CognitoIdentityServiceProvider.AdminCreateUserResponse = await new Promise(resolve => {
cognitoidentityserviceprovider.adminCreateUser(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data); // successful response
console.log("adminCreateUser complete")
resolve(data)
}
})
});
let identity: CognitoIdentity.GetIdResponse = await new Promise(resolve => {
setPassword(phone_number, resolve)
});
let user_attributes = adminCreateUserResonse.User.Attributes
let sub = user_attributes.find(a => a.Name == "sub")
}
function setPassword(phone_number: string, resolve: any) {
var cognitoidentityserviceprovider = new CognitoIdentityServiceProvider();
let password = generator.generate({
length: 32,
numbers: true,
symbols: true,
lowercase: true,
uppercase: true
});
var setPasswordParams = {
Password: password, /* required */
UserPoolId: process.env.USER_POOL_ID, /* required */
Username: phone_number, /* required */
Permanent: true
};
console.log("adminSetUserPassword")
cognitoidentityserviceprovider.adminSetUserPassword(setPasswordParams, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data); // successful response
console.log("adminSetUserPassword complete")
initiateAuth(phone_number, password, resolve)
}
})
}
function initiateAuth(phone_number: string, password: string, resolve: any) {
var cognitoidentityserviceprovider = new CognitoIdentityServiceProvider();
let initiateAuthParams = {
AuthFlow: "ADMIN_USER_PASSWORD_AUTH",
AuthParameters: {
"USERNAME" : phone_number,
"PASSWORD" : password
},
UserPoolId: process.env.USER_POOL_ID, /* required */
ClientId: process.env.CLIENT_ID
}
console.log("adminInitiateAuth")
cognitoidentityserviceprovider.adminInitiateAuth(initiateAuthParams, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data); // successful response
console.log("adminInitiateAuth complete")
getId(data, resolve)
}
})
}
function getId(data: CognitoIdentityServiceProvider.AdminInitiateAuthResponse, resolve: any) {
const cognitoidentity = new CognitoIdentity()
let login_provider = "cognito-idp." + process.env.REGION + ".amazonaws.com/" + process.env.USER_POOL_ID
console.log("login_provider: " + login_provider)
let getIdParams = {
"AccountId": process.env.AWS_ACCOUNT_ID,
"IdentityPoolId": process.env.IDENTITY_POOL_ID,
"Logins": {}
}
getIdParams.Logins[login_provider] = data.AuthenticationResult.IdToken
console.log("getId")
cognitoidentity.getId(getIdParams, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data); // successful response
console.log("getId complete")
resolve(data)
}
})
}
Upvotes: 1