【问题标题】:How to get the Cognito Identity id in AWS Lambda如何在 AWS Lambda 中获取 Cognito 身份 ID
【发布时间】:2015-07-07 20:00:53
【问题描述】:

如何获取调用 AWS Lambda 函数的用户(通过 AWS Cognito 登录)的身份 ID?我是否必须使用 Lambda 函数上的 SDK 来获取身份 ID?

【问题讨论】:

  • 您是在谈论将 Cognito 同步作为事件源吗?它应该在活动中以event.Records[0].cognitosync.identityId 的形式提供。
  • 在这种情况下,我从浏览器的 Javascript SDK 中使用它。在这种情况下,event.Records 似乎不可用。
  • 啊,明白了。以为您是指 Cognito 事件源,而不是使用 Cognito 进行身份验证。

标签: amazon-web-services amazon-cognito aws-lambda


【解决方案1】:

在 lambda 函数内的 AWS javascript SDK 中,只需使用 context.identity.cognitoIdentityId 它对我有用

【讨论】:

  • 我正在这样做,但是在 java 函数中,它是 context.getIdentity().getIdentityId() 并且它只返回一个空字符串。如果我记录 context.getIdentity() 它返回“lambdainternal.api.LambdaCognitoIdentity@42f48531”。有什么想法吗?
  • 我真的很好奇:你做了什么让这件事发生?您对 Lambda 或 API Gateway 做了哪些特殊配置?
  • 我怀疑@JamesParker 不小心使用了未经身份验证的CognitoIdentityCredentials,这对于浏览器使用的示例文档来说太容易了。
  • 如何使用 POSTMAN 进行测试...当使用 postman 发送请求时,lambda 的 event.requestContext.identity.cognitoAuthenticationProvider 值为空
  • context.identity.cognitoIdentityId 在我的情况下为空
【解决方案2】:

如果您通过 API Gateway,您可以将 cognito id(以及用户 arn 和其他有用信息)传递给 Lambda。这为我解决了这个问题。

http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html

【讨论】:

  • 谢谢,这正是我所需要的。
  • API 网关我们添加了 cognito 身份验证。在 api 方法中添加了“$context.identity.cognitoIdentityPoolId”,但是当我们在 JAVA lambda 函数中访问它时它是空的。我们使用邮递员作为客户端并设置授权令牌。缺少什么?
  • @Mr.PramodAnarase 如果您要添加类似 Authorization: Bearer SOME_TOKEN 的内容,其中 SOME_TOKEN 是 InitiateAuth / RespondToAuthChallenge 流返回的 Id 或 Auth 令牌,则您正在使用 Cognito 用户池进行身份验证,并且因此还没有身份池 ID。评论不足以描述此处的完整流程:),但您希望使用CognitoIdentityCredentials 进行身份验证,它在后台使用 STS 来获取将设置它的临时访问密钥。
  • @SimonBuchan 我在登录调用中使用 userPool 进行身份验证,并使用 AWS.CognitoIdentityCredentials 更新我的 aws 凭据,我看到它在我的身份池中注册了身份,但是 accessToken 和 idToken 仍然相同.我在对其他端点的经过身份验证的调用中使用它们。我应该为我的其他 api 调用使用其他东西来进行身份验证以填充身份属性吗?我想我在这里遗漏了一些简单的东西,但是我一生都无法弄清楚在游泳池注册后该怎么做。谢谢!
  • 你好像很困惑? TL;DR:你得到你发送的内容:令牌 -> 用户池身份验证,凭据 -> 身份池身份验证。您需要身份池身份验证才能在 lambda 上下文中获取认知身份(池)ID(仅在直接调用它时)。如果您正在使用用户池身份验证,则应改为使用 API 网关中的 cognito 用户池身份验证器或 JWT 验证器来验证并从令牌中提取声明,这将为您提供可读属性。
【解决方案3】:

如果其他人偶然发现了这一点,我认为这会对您有很大帮助。

请注意,这只适用于您使用 Cognito 用户池授权器的情况。如果您想将 AWS_IAM 与 Cognito Identitys 一起使用,请查看我的 github 示例 https://github.com/VictorioBerra/js-cognito-auth-example(请阅读下面的编辑区域)

如果您选中了“使用 Lambda 代理集成”,那么您将无权访问请求模板映射。但是您可以在 lambda 函数中访问令牌内的声明:

exports.handler = (event, context, callback) => {
    //create a response
    const response = {
      statusCode: 200,
      body: JSON.stringify({
          "user email": event.requestContext.authorizer.claims.email,
      }),
    };
    callback(null, response);    
};

编辑 - 有关使用 AWS_IAM 作为 APIG 授权方的更多信息

基本上,您需要使用 AWS_IAM 保护您的 APIG,并且您必须通过 Cognito 联合身份进行身份验证,该身份将返回 sessionToken example using user pools。这就是使 AWS IAM 凭证临时的原因。 现在您拥有了向 APIG 进行身份验证所需的一切。

要对此进行测试,请下载postman 的桌面版本,输入您的 API URI(从阶段区域获取),然后在授权下填写 Sig4 签名所需的 5 个字段。您将看到 lambda 函数中的“event.identity”对象加载了诸如user 对象之类的属性。

如果您想使用 APIG 自动生成的 SDK,它内置了一个工厂,该工厂采用 accessKeysecrettoken 并为您签名所有内容。与 aws-sdk 相同。您可以使用这三个项目初始化凭据,它会自动使用这些临时凭据为您签署所有请求。如果您想直接手动使用 window.fetch、request、curl(在此处插入 http 客户端)手动访问您的 API,您可以calculate your own Sig4(注意它可能有点复杂或use a modern library to do it for you

另外记录一下,在进行研究时,我注意到如果您不想使用 AWS_IAM 作为 APIG 授权者,并且您想使用“Cognito Identity Pool Authorizer”,这是 APIG 下拉列表中的一个新选项如果您只是将JWT gained from a successful Cognito popl auth 作为授权标头传递给 APIG,仍然可以在 lambda 事件中获得大量有关用户的信息。在 JWT 内部有很多属性,您可以在池设置中自定义这些属性。

IMO 专业意见我认为使用 AWS_IAM 临时信用授权器是首选。这样,您可以在 Cognito 身份(Facebook、Twitter、池等)中使用任意数量的不同 IdP


【讨论】:

  • 请注意,这是使用用户池而不是身份池进行身份验证,因此没有身份ID。是的,Cognito 非常令人困惑。
  • 谢谢西蒙我更新了我的答案。我实际上花了一些时间为此工作并为它创建了一个 github 项目。
  • event.requestContext.authorizer 在我的 lambda 中不可用。使用 AWS_IAM 和“Lambda 代理集成”运行。有任何想法吗?备注:Cognito 和 IAM 是纯粹的地狱。 WAAAY 到复杂。
  • @Marc 如果您没有authorizer,那么您调用 APIG 的机会可能未经过身份验证。基本上,您需要使用 AWS_IAM 保护您的 APIG,并且您必须通过 Cognito 联合身份进行身份验证,该身份将返回 sessionToken。
  • 我做了所有这一切,并对其进行了验证。但根据文档授权者实际上并不存在这种情况。我认为它只存在于 USERPOOL 授权方。您可以通过 event.requestContext.identity.cognitoAuthenticationProvider 获取身份。不幸的是,池中只有用户的“子”属性。没有其他字段。
【解决方案4】:

根据the docs,看起来有关身份提供者的信息仅可用于通过移动 SDK 进行调用。

要解决此问题,一种选择是将身份 ID 作为事件的一部分手动传递给函数。假设您正在执行AWS.config.credentials = new AWS.CognitoIdentityCredentials(...) 之类的操作,那么您应该能够通过AWS.config.credentials.identityId 获取 ID(在刷新凭据之后)。

编辑:身份验证的更好选择是让 Cognito/IAM 处理它,并假设用户可以成功调用 Lambda 函数,这意味着他们被允许。在这种情况下,要管理每个用户的验证,请查看 whitelisting

【讨论】:

  • 是的,这行得通,但恐怕我无法在 Lambda 函数中验证身份,并且不能保证调用该函数的用户与他所说的相同。我应该对此感到担忧吗?有办法解决吗?
  • 嗯...但是用户能够调用您的函数的唯一方法是如果他们具有“有效”身份。您的 Cognito 池设置了您期望的合约,例如如果您希望他们首先使用 Facebook 登录,或者您甚至可以在自定义身份提供商中拥有自己的验证方法。所以 Lambda 函数不需要担心验证。但我觉得我在这里遗漏了一些东西......你看到什么情况下你需要在 Lambda 函数中进行验证?
  • 例如:如果我想调用一个函数来创建/编辑/删除某些东西,比如在 DynamoDB 上,但我必须验证用户以确保他有权执行此操作。跨度>
  • Whitelisting?或者更适合这种情况的解决方案是自定义提供程序。恕我直言,Cognito/IAM/您的应用程序应该负责验证,一旦用户调用一个意味着他们被允许的函数。
  • @WilliamGaul 不幸的是,在这种情况下,文档有点误导。无论使用何种 SDK,只要凭证来自 Amazon Cognito authflow,身份都应该可用。
【解决方案5】:

我的观察如下。

如果您使用签名请求调用 API 网关,您实际上提供了可以通过(JS SDK)提取的访问密钥、秘密和会话令牌:

AWS.config.credentials = new AWS.CognitoIdentityCredentials(...)
AWS.config.credentials.get(..)

并假设您的 lambda 是通过 LAMBDA_PROXY 和 Authorizer AWS_IAM 从 API-Gateway 调用的。您只能通过以下方式访问 lambda 中的用户内容:

exports.create = function (event, context) {
   secdata = event.requestContext.identity.cognitoAuthenticationProvider;
}

然后,除了其他东西之外,您将获得 cognito UserPool User 的“子”。因此,如果您真的想了解更多有关用户的信息,您似乎需要通过 SDK 调用再次询问 AWS。

【讨论】:

  • 在这种情况下,secdata 将是一个必须解析的类似"cognito-idp.us-east-1.amazonaws.com/us-east-1_3UxKMbgEq,cognito-idp.us-east-1.amazonaws.com/us-east-1_3UxLObgEq:CognitoSignIn:c40aabc8-9b21-4aa5-b296-12175450e28e" 的字符串,CognitoSignIn: 之后的部分是用户 ID。
【解决方案6】:

对于 Python Lambda,通过 Javascript AWS SDK / Cognito / Amplify 调用...

https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html

context.identity.cognito_identity_id

它应该看起来像这样:

{aws region}:{ GUID }

假设您使用的是身份池,这将返回 Cognito 联合身份,可用于细粒度的访问控制。这比依赖包含身份 ID 的 Javascript 有效负载更安全。

Cognito 身份池身份验证角色需要具有 Lambda:InvokeFunction 策略,否则用户将无法首先调用该函数。

编辑:这在直接调用 Lambda 函数时有效,而不是通过 API 网关。

Edit2:允许 Cognito 用户调用 lambda,因为它在 IAM Cognito Auth 角色中明确设置。

【讨论】:

    【解决方案7】:

    我使用的是 Kotlin,而我的 Lambda 处理程序是

    override fun handleRequest(event: APIGatewayProxyRequestEvent, context: Context): APIGatewayProxyResponseEvent 
    

    但是event.requestContext 没有authorizer。解决方案是升级 build.gradle 中的依赖项 com.amazonaws:aws-lambda-java-events:2.1.0com.amazonaws:aws-lambda-java-events:2.2.7。之后,我得到的用户名如下。

    val claims = requestContext.authorizer["claims"] as Map<String, String>
    println(claims["cognito:username"])
    println(claims["email"])
    

    【讨论】:

      猜你喜欢
      • 2020-02-16
      • 2017-07-26
      • 2022-06-20
      • 2020-11-04
      • 2022-07-18
      • 2017-02-02
      • 2015-11-26
      • 2020-07-01
      • 1970-01-01
      相关资源
      最近更新 更多