如何在 AWS Lambda 中获取 Cognito Identity ID

How to get the Cognito Identity id in AWS Lambda

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

根据 the docs,有关身份提供者的信息似乎仅可用于通过 Mobile SDK 进行的调用。

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

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

在 AWS javascript SDK 里面的 lambda 函数只使用 context.identity.cognitoIdentityId 它对我有用

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

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

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

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

如果您选中了 "Use Lambda Proxy Integration",那么您将无权访问请求模板映射。但是您可以在 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 联合身份验证,这将 return sessionToken example using user pools。这就是使 AWS IAM 凭证成为临时凭证的原因。 现在您拥有了对 APIG 进行授权所需的一切。

要对此进行测试,请下载 postman 的桌面版,输入您的 API URI(从阶段区域获取),然后在授权下填写 Sig4 所需的 5 个字段签署。您会看到 'event.identity' object 在您的 lambda 函数中加载了 user object.

等属性

如果您想使用 APIG auto-generated SDK,它内置了一个工厂,该工厂采用 accessKeysecrettoken 并为您签署一切。与 aws-sdk 相同。您可以使用这三个项目初始化凭据,它会自动使用这些临时凭据为您签署所有请求。如果你想直接用 window.fetch、request、curl(在这里插入 http 客户端)手动点击你的 API,你可以 calculate your own Sig4 (beware it can be a little complicated or 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 事件中获得大量关于用户的信息header。在 JWT 中有很多属性,您可以在池设置中自定义这些属性。

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


我的观察如下。

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

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

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

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

然后你会得到,除了其他东西,cognito UserPool User 的"sub"。因此,如果您真的想了解更多有关用户的信息,看来您需要通过 SDK 调用再次询问 AWS。

对于 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 }

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

Cognito Identity Pool Auth Role 需要有 Lambda:InvokeFunction 政策,否则用户将无法首先调用该功能。

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

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

我使用的是 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"])