【问题标题】:How to fetch Amazon Cognito Identity ID (user_identity_id) for the user from the lambda function?如何从 lambda 函数获取用户的 Amazon Cognito 身份 ID (user_identity_id)?
【发布时间】:2022-07-18 23:58:12
【问题描述】:

在 Amplify 文档中,Storage/File access levels 部分下有一段说明:

文件存储在 private/{user_identity_id}/ 下,其中 user_identity_id 对应于该用户的唯一 Amazon Cognito 身份 ID。

如何从 lambda 函数中获取 user_identity_id?

对 lambda 的请求被授权,event.requestContext.authorizer.claims 对象可用,我可以看到用户数据,但看不到 user_identity_id。

编辑:现在我看到有一个字段event.requestContext.identity.cognitoIdentityId,但值是null。还是得想办法获取。

【问题讨论】:

    标签: javascript amazon-s3 aws-lambda amazon-cognito aws-amplify


    【解决方案1】:

    好的,所以没有正确的方法来映射 Cognito 身份 ID 和 Cognito 用户。有一个冗长的讨论 here 可以找到一些解决方法。现在,我将使用this 解决方案,您可以将自定义属性(很可能是子属性)指定为文件夹名称,而不是 identity_id。

    编辑:还有另一种解决方案可能会有所帮助(在互联网上的某个地方找到,我验证它有效)

    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.com/${process.env.USERPOOLID}`;
      return {
        IdentityPoolId: `${process.env.IDENTITY_POOL_ID}`,
        Logins: {
          [loginsKey]: jwtToken,
        },
      };
    }
    

    【讨论】:

      【解决方案2】:

      如果用户通过 AppSync 服务通过 graphql 访问 lambda,则存储身份 event.identity.owner

      这是我用来从事件中提取 user_identity_id 的一些打字稿代码。但是,用户并不总是调用 lambda direct sp,如果来自授权的 IAM 角色,user_identity 也可以基于。

      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;
        }
      }
      

      【讨论】:

        【解决方案3】:

        对于仍在为此苦苦挣扎的其他人,我终于能够使用aws-sdk for JavaScript v3 在通过 API-Gateway 调用的 Lambda 函数中获取 Cognito 用户的 IdentityId 和凭据,其中 Cognito User Pool Authorizer 从 Cognito 用户的身份 jwtToken 传递进入请求的Authorization 标头。

        这是我的 JavaScript Lambda 函数中使用的代码:

        const IDENTITY_POOL_ID = "us-west-2:7y812k8a-1w26-8dk4-84iw-2kdi849sku72"
        const USER_POOL_ID = "cognito-idp.us-west-2.amazonaws.com/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: 'ALALA2RZ7KTS7STD3VXLM',
                //    secretAccessKey: '/AldkSdt67saAddb6vddRIrs32adQCAo99XM6',
                //    sessionToken: 'IQoJb3JpZ2luX2VjEJj//////////...', // sessionToken cut for brevity 
                //    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;
        }
        

        在 Cognito 用户登录到我的应用程序后,我可以在我的 React-Native 应用程序中使用 aws-amplify 和 fetch() 的 Auth 指令,通过向我的 API 发送请求来调用上面显示的 lambda 函数- 通过调用以下代码触发网关(使用Cognito User Pool Authorizer 进行身份验证):

        import { Auth } from 'aws-amplify';
        var APIGatewayEndpointURL = 'https://5lstgsolr2.execute-api.us-west-2.amazonaws.com/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)
                  })
        }
        

        有关如何使用aws-amplify 进行身份验证的更多信息可以在这里找到https://docs.amplify.aws/ui/auth/authenticator/q/framework/react-native/#using-withauthenticator-hoc

        【讨论】:

          猜你喜欢
          • 2020-02-16
          • 2015-07-07
          • 2020-07-01
          • 2015-11-26
          • 2018-12-11
          • 2020-04-21
          • 2016-10-23
          • 2017-07-26
          • 2016-09-26
          相关资源
          最近更新 更多