admin管理员组

文章数量:1392095

In the Amplify documentation, under the Storage/File access levels section there is a paragraph that states:

Files are stored under private/{user_identity_id}/ where the user_identity_id corresponds to the unique Amazon Cognito Identity ID for that user.

How to fetch user_identity_id from the lambda function?

Request to the lambda is authorized, the event.requestContext.authorizer.claims object is available, I can see the user data, but not the user_identity_id.

EDIT: Now I see that there is a field event.requestContext.identity.cognitoIdentityId, but the value is null. Still need to find the way to fetch it.

In the Amplify documentation, under the Storage/File access levels section there is a paragraph that states:

Files are stored under private/{user_identity_id}/ where the user_identity_id corresponds to the unique Amazon Cognito Identity ID for that user.

How to fetch user_identity_id from the lambda function?

Request to the lambda is authorized, the event.requestContext.authorizer.claims object is available, I can see the user data, but not the user_identity_id.

EDIT: Now I see that there is a field event.requestContext.identity.cognitoIdentityId, but the value is null. Still need to find the way to fetch it.

Share Improve this question edited Jan 11, 2022 at 14:47 Pavle asked Jan 11, 2022 at 11:54 PavlePavle 2074 silver badges12 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3

Ok, so there's no right way to map Cognito identity ID and Cognito user. There is a lengthy discussion here where a couple of workarounds can be found. For now, I'm going to use this solution where, instead of identity_id, you can specify a custom attribute (most likely a sub) as a folder name.

EDIT: There is another solution that might help (found somewhere on the internet, and I verified that it works)

const AWS = require('aws-sdk')
const cognitoIdentity = new AWS.CognitoIdentity();

function getCognitoIdentityId(jwtToken) {
  const params = getCognitoIdentityIdParams(jwtToken);
  return cognitoIdentity
    .getId(params)
    .promise()
    .then(data => {
      if (data.IdentityId) {
        return data.IdentityId;
      }
      throw new Error('Invalid authorization token.');
    });
}

function getCognitoIdentityIdParams(jwtToken) {
  const loginsKey = `cognito-idp.${process.env.REGION}.amazonaws./${process.env.USERPOOLID}`;
  return {
    IdentityPoolId: `${process.env.IDENTITY_POOL_ID}`,
    Logins: {
      [loginsKey]: jwtToken,
    },
  };
}

If the user accesses the lambda through graphql via the AppSync service then the identity is stored event.identity.owner

Here is some typescript code I use to pull the user_identity_id from the event. However, the user doesn't always call the lambda direct sp the user_identity can also be based in if from an authorized IAM role.

export function ownerFromEvent(event: any = {}): string {
  if (
    event.identity.userArn &&
    event.identity.userArn.split(":")[5].startsWith("assumed-role")
  ) {
    // This is a request from a function over IAM.
    return event.arguments.input.asData.owner;
  } else {
    return event.identity.owner;
  }
}

For anyone else still struggling with this, I was finally able to use the aws-sdk for JavaScript v3 to obtain a Cognito User's IdentityId & Credentials in a Lambda Function invoked via API-Gateway with a Cognito User Pool Authorizer from the Cognito User's identity jwtToken passed into the Authorization header of the request.

Here is the code used in my JavaScript Lambda Function:

const IDENTITY_POOL_ID = "us-west-2:7y812k8a-1w26-8dk4-84iw-2kdi849sku72"
const USER_POOL_ID = "cognito-idp.us-west-2.amazonaws./us-west-2_an976DxVk"
const { CognitoIdentityClient } = require("@aws-sdk/client-cognito-identity");
const { fromCognitoIdentityPool } = require("@aws-sdk/credential-provider-cognito-identity");

exports.handler = async (event,context) => {
        const cognitoidentity = new CognitoIdentityClient({
             credentials:  fromCognitoIdentityPool({
             client: new CognitoIdentityClient(),
             identityPoolId: IDENTITY_POOL_ID,
                 logins: {
                     [USER_POOL_ID]:event.headers.Authorization
                 }
             }),
        });

        var credentials = await cognitoidentity.config.credentials()
        console.log(credentials)
        // {
        //    identityId: 'us-west-2:d393294b-ff23-43t6-d8s5-59876321457d',
        //    accessKeyId: '**ACCESS_KEY_ID_HERE**',
        //    secretAccessKey: '**SECRET_ACCESS_KEY_HERE**',
        //    sessionToken: '**SESSION_TOKEN_HERE**', 
        //    expiration: 2022-07-17T08:58:10.000Z
        //  }
        var identity_ID =  credentials.identityId
        console.log(identity_ID)
        // us-west-2:d393294b-ff23-43t6-d8s5-59876321457d

        const response = {
            statusCode: 200,
            headers: {
                "Access-Control-Allow-Headers": "*",
                "Access-Control-Allow-Origin": "*",
                "Access-Control-Allow-Methods" : "OPTIONS,POST,GET,PUT"
             }, 
             body:JSON.stringify(identity_ID)
        };
        return response;
}

After a Cognito User has signed in to my application, I can use the Auth directive of aws-amplify and fetch() in my React-Native app to invoke the lambda function shown above by sending a request to my API-Gateway trigger (authenticated with a Cognito User Pool Authorizer) by calling the following code:

import { Auth } from 'aws-amplify';
var APIGatewayEndpointURL = 'https://5lstgsolr2.execute-api.us-west-2.amazonaws./default/-'
var response = {}

async function getIdentityId () {   
       var session = await Auth.currentSession()
       var IdToken = await session.getIdToken()
       var jwtToken = await IdToken.getJwtToken()

       var payload = {}
       
       await fetch(APIGatewayEndpointURL, {method:"POST", body:JSON.stringify(payload), headers:{Authorization:jwtToken}})
         .then(async(result) => {
             response = await result.json()
             console.log(response)
          })
}

More info on how to Authenticate using aws-amplify can be found here https://docs.amplify.aws/ui/auth/authenticator/q/framework/react-native/#using-withauthenticator-hoc

本文标签: