I have an AWS Lambda function which is attached as a trigger to a user pool on the "Post confirmation" event.
I need to get the IdentityId of the user that has been created, how can I do that?
Here is my code:
'use strict';
var AWS = require('aws-sdk');
var region = 'eu-west-1'
var sqs = new AWS.SQS({region : region});
var s3 = new AWS.S3({region : region});
var util = require('util');
let awsAccountId = 'xx';
let queueName = 'xx';
// this function saves public user data to a bucket where clients can access it.
let putObjectToS3 = (bucket, key, data, contentType, callback) => {
let params = {
Bucket : bucket,
Key : key,
Body : data,
CacheControl: "max-age=864000",
ContentType: contentType
}
s3.putObject(params, callback);
}
let sendSQSMessage = (dataStr, callback) => {
let queueURL = 'https://sqs.' + region + '.amazonaws.com/' + awsAccountId + '/' + queueName;
let params = {
MessageBody: dataStr,
QueueUrl: queueURL
};
sqs.sendMessage(params, callback);
}
exports.handler = (event, context, callback) => {
console.log('event', event)
let S3key = 'publicuserdata/' + event.request.userAttributes.sub + '.json';
let publicUserData = {};
publicUserData['IdentityId'] = context.identity.cognitoIdentityId; //doesn't seem to work
publicUserData['region'] = event.region;
publicUserData['userName'] = event.userName;
publicUserData['userPoolId'] = event.userPoolId;
let finishLambdaCallback = (err, result) => {
if (err) {
console.log('error', err)
} else {
console.log('success', result)
context.done(null, event)
}
};
let funcOne = (callback) => {
let data = util.inspect(context)
//let data = JSON.stringify(context, null, 2)
putObjectToS3( 'files.example.org',
S3key,
data,
'application/json',
callback);
}
let funcTwo = (callback) => {
let data = util.inspect(context)
//let data = JSON.stringify(context, null, 2)
sendSQSMessage(data, callback);
}
funcOne(() => {funcTwo(finishLambdaCallback)})
};
Sorry, this is not possible at this point. The identityId is not passed in the lambda trigger. We have heard this request in the past and I will +1 the feature request on your behalf.
Only way I can think of doing this as a workaround is to store the identityId in one of the custom attributes which are passed to the lambda function.
+2
@koehn tell me what you are trying to do - the big picture..... I might be able to help as I spent days digging around this stuff.
Those who seek answers might be interested in this http://stackoverflow.com/questions/42386180/aws-lambda-api-gateway-with-cognito-how-to-use-identityid-to-access-and-update
@lunikernel that's what I'm using now, but still no way to get the identityId in Post Confirmation Trigger
+1
any update on this one? Documentation does not specify all fields....the stackoverflow link above makes this just overly complicated (when really its quite simple)
Use case:
upon user creation a cognitoID (namely sub) is created. I want to use this sub to key off of in my database from a post confirmation lambda trigger
SRC: http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html#cognito-user-pools-lambda-trigger-syntax-post-confirmation
@itrestian Since this hasn't been implemented so far I need a workaround for this and therefore, I was thinking about your post. But how could I add the identityId in one of the custom attributes during signup? I didn't find a way to get the identityId after signing up a user to add the identityId to the custom attributes.
My use case:
userPool.signUp(email, password, [], null (err, result) => { console.log(result.user); });
result.user doesn't provide any identityId value as far as I know. Is there any alternative option to get the identityId here?
I have a post-confirmation triggered lambda right now that is currently failing (silently) to put to DynamoDB and in my search for clues I came across this post. While it's not at all what I was looking for I do have some recent experience on the subject of your issue, so thought I could maybe get my fulfillment for the day but helping someone else if not solving my own problem.
@tschmidleithner - your result should be of type CognitoUserSession...
class CognitoUserSession {
constructor(data: ICognitoUserSessionData);
public getIdToken(): CognitoIdToken;
public getRefreshToken(): CognitoRefreshToken;
public getAccessToken(): CognitoAccessToken;
public isValid(): boolean;
}
Use the getIdToken() method to retrieve the idToken...
const userTokens = result.getIdToken().getJwtToken()
Then isolate the token's payload and parse it...
const idTokenPayload = userTokens.idToken.split('.')[1];
const user = JSON.parse(sjcl.codec.utf8String.fromBits(sjcl.codec.base64url.toBits(idTokenPayload)));
The resulting object's properties will vary by the particulars of each setup but suffice it to say that the idToken contains all of which has been deemed 'readable' from AWS Console --> Cognito --> User Pools -->
There are a few differences but you should see roughly the same data in a Cognito triggered Lambda at event.request.userAttributes.
@Aleolly @crowdwave @koehn @itrestian - afaik the identityId is the set of tokens (accessKeyId, secretAccessKey, & sessionToken) for a given user session... so if I'm missing something and that's not what you're after let me know. If, however, that is what you're looking for then you should gladly find those tokens in the lambda's execution environment variables.
const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
const sessionToken = process.env.AWS_SESSION_TOKEN
Hope this helps - happy coding.
Hey Folks,
After some debugging, this is possible. The CognitoID (ie sub) is passed into the event parameter for lambda from post-confirmation trigger. I'm certain most folks know this by now, but i just wanted to post for future "lost" users.
function getCognitoId(event){
return event.request.userAttributes.sub;
}
@jmmclean we were asking about "IdentityId" not "sub" and as @itrestian said, it's not possible for that trigger, but yes, we should use the sub and not the identityId.
@killbox-security with "IdentityId" we refer to something like "region:uuid" that is not a cognito field, and if you don't allow unauthenticated users you can't get it before login, that's what I understood, so you can't have it in post confirmation trigger
@aleolly there is no "identityid" with cognito. There are three tokens passed back from a successful authentication, being refresh, identity, and access. The ID that I would assume this thread is referring to is the cognito ID for a given user, which can be found after decoding the Identity JWT as the "sub" attribute within the payload.
@jmmclean that's what I mean with "but yes, we should use the sub and not the identityId"
This issue is generated by misinterpretation of some example provided on aws blog an I assure you that there are many dev have found themselves stuck on this.
If you read the thread that's the problem an that's why @itrestian wrote that is not possible and suggest to save the identityId as custom cognito field.
Sub field was ever passed to post confirmation trigger I guess, so it can't be the issue.
I need to make this case as obvious as possible:
arn:aws:s3:::mybucket/${cognito-identity.amazonaws.com:sub}/avatar.jpg Both cases cause me trauma for longer than i'd like to admit. Still can't decide what should I use as identifier for our user table.
@killbox-security Your code seems to work well.
In my case I've linked my user pool with an identity pool. After authentication, the sub property of the user contains a unique identifier, for instance "d5632b5f-6dd1-4936-956b-ea02d8276fdb".
This could be easily used to link to data in another database.
Well, I'm using ReactXP and if the code works on native (Babel), It fails on Web (webpack). I switched to using jwt-decode.
@itrestian adding the identityId to a custom attribute is still the only way of doing that? :/
Most helpful comment
+1
any update on this one? Documentation does not specify all fields....the stackoverflow link above makes this just overly complicated (when really its quite simple)
Use case:
upon user creation a cognitoID (namely sub) is created. I want to use this sub to key off of in my database from a post confirmation lambda trigger
SRC: http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html#cognito-user-pools-lambda-trigger-syntax-post-confirmation