sst.dev icon indicating copy to clipboard operation
sst.dev copied to clipboard

is there a way to retrieve cog users attributes etc using the cognitoIdentityId ?

Open walshe opened this issue 7 years ago • 6 comments

or any thing else in the request..

I know I could pass in the email address from the frontend and use adminGetUser() but wondered if theres a way using the default stuff passed to the lambda event:

{
    "resource": "/appToken",
    "path": "/appToken",
    "httpMethod": "GET",
    "headers": {
        "Accept": "application/json",
        "accept-encoding": "gzip, deflate, br",
        "Accept-Language": "en-US,en;q=0.9,la;q=0.8",
        "CloudFront-Forwarded-Proto": "https",
        "CloudFront-Is-Desktop-Viewer": "true",
        "CloudFront-Is-Mobile-Viewer": "false",
        "CloudFront-Is-SmartTV-Viewer": "false",
        "CloudFront-Is-Tablet-Viewer": "false",
        "CloudFront-Viewer-Country": "US",
        "content-type": "application/json",
        "Host": "sh0sqilix3.execute-api.us-east-1.amazonaws.com",
        "origin": "http://localhost:3000",
        "Referer": "http://localhost:3000/login",
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
        "Via": "2.0 e81b6793c2b9879878a5c7ea08e930ec3d.cloudfront.net (CloudFront)",
        "X-Amz-Cf-Id": "ddddddd-6JeD94veDuL19m7xg==",
        "x-amz-date": "20180329T012958Z",
        "x-amz-security-token": "Ago.....adadasdfasdfasdfxxxx",
        "X-Amzn-Trace-Id": "Root=1-5abadasdd22c25e9c3dd709b",
        "X-Forwarded-For": "67.254asdasd.173, 204.246.168.112",
        "X-Forwarded-Port": "443",
        "X-Forwarded-Proto": "https"
    },
    "queryStringParameters": null,
    "pathParameters": null,
    "stageVariables": null,
    "requestContext": {
        "resourceId": "nzgdtl",
        "resourcePath": "/appToken",
        "httpMethod": "GET",
        "extendedRequestId": "Ee8vkHsToAMFa0A=",
        "requestTime": "29/Mar/2018:01:29:58 +0000",
        "path": "/dev/appToken",
        "accountId": "45345",
        "protocol": "HTTP/1.1",
        "stage": "dev",
        "requestTimeEpoch": 1522286998876,
        "requestId": "b1a59a78-32werwer9c7e-7750ea569b7f",
        "identity": {
            "cognitoIdentityPoolId": "us-east-1werwerae-4f12-9af7-dfa7af96fac2",
            "accountId": "werwer",
            "cognitoIdentityId": "us-east-234234880d-40c48951cf7b",
            "caller": "AROAJKAEMPFSM234234BLC2:CognitoIdentityCredentials",
            "sourceIp": "67.254.215.173",
            "accessKey": "343434",
            "cognitoAuthenticationType": "authenticated",
            "cognitoAuthenticationProvider": "cognito-idp.us-east-1.amazxxxxx3f1",
            "userArn": "arn:awdfsdfsdfIdentityCredentials",
            "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
            "user": "AROAJKAsdfsdfsMBKDBLC2:CognitoIdentityCredentials"
        },
        "apiId": "gjhgjgjg"
    },
    "body": null,
    "isBase64Encoded": false
}

walshe avatar Mar 29 '18 01:03 walshe

@walshe I don't think there is a direct way. But there is a hack that we use internally. The cognitoAuthenticationProvider is basically the User Pool Id of the user that you can use to get the attributes. It is formatted a bit weirdly but you can parse it out and use it.

jayair avatar Mar 30 '18 22:03 jayair

actually I just see its all contained in payload session.getIdToken() on the client, so I could pass it it from there

walshe avatar Mar 31 '18 00:03 walshe

this cognito api is so confusing

by the way, in the notes api how come you associate a note with a cognitoIdentityId rather than the 'sub' which is at the end of the cognitoAuthenticationProvider field

"cognitoAuthenticationProvider": "cognito-idp.us-east-1.amazonaws.com/us-east-1_Wg0Dp2n5r,cognito-idp.us-east-1.amazonaws.com/us-east-1_Wg0Dp2n5r:CognitoSignIn:c45b94b4-57e5-41gc-86c3-6ed5e41212359",

The reason i say this is because when it comes to lokoing up users in the cognito console, then they all get listed there by sub, with no sign of a cognitoIdentityId at all . @jayair

walshe avatar Mar 31 '18 13:03 walshe

@walshe It can be done either way. But say you had multiple auth providers (Facebook and Google); the Identity Id gives you a unified id for the user.

jayair avatar Mar 31 '18 20:03 jayair

I see. Btw @jayair whats your opinion on this as a way to get info on a user groups and attributes.. here is what I am doing:

I pass the email addr from frontend (used in the login form) to a protected lambda. In there i use email param to:

  1. call var user = await cognitoIdentityServiceProvider.adminGetUser({ UserPoolId: process.env.USER_POOL_ID, Username: email }).promise()
  2. check event.requestContext.identity.cognitoAuthenticationProvider.includes(user.Username)) (just in case a logged in user maliciously tried to pass in someone else's email address to try to obtain admin access of some sort)
  3. then use the attributes from the user obj in (1) as i know they are belonging to the caller
  4. call var groupsResult = await cognitoIdentityServiceProvider.adminListGroupsForUser({UserPoolId:process.env.USER_POOL_ID, Username: user.Username}).promise() to get the groups for the user. Here the Username param is actually the sub of the cognito user
  5. I process groupsResult to check that user is in 'admin' group i have configued

walshe avatar Mar 31 '18 21:03 walshe

@walshe Yeah that makes sense. I haven't tried it but it looks okay.

jayair avatar Apr 02 '18 18:04 jayair