gpt4 book ai didi

aws-lambda - 带有 Cognito 的 AWS Lambda API 网关 - 如何使用 IdentityId 访问和更新 UserPool 属性?

转载 作者:行者123 更新时间:2023-12-03 07:50:52 26 4
gpt4 key购买 nike

好的,我现在已经进入了这几天并且已经取得了重大进展,但仍然完全被基本面难住了。

我的应用程序使用 Cognito 用户池来创建和管理用户 - 这些在 S3 上通过他们的 IdentityId 进行标识。我的每个用户都有自己的 S3 文件夹,AWS 会自动为他们提供一个与用户的 IdentityId 相同的文件夹名称。

我需要将 IdentityId 与其他 Cognito 用户信息相关联,但无法弄清楚如何。

我需要的关键是能够识别给定 IdentityId 的用户名和其他认知用户属性 - 这非常困难。

因此,第一场战斗是弄清楚当 Cognito 用户通过 AWS API 网关发出请求时如何获取 IdentityId。最终我解决了这个问题,现在我有一个 Cognito 用户,他向 API 网关发出请求,而我背后的 Lambda 函数现在有了 IdentityId。那一点有效。

但是我完全不知道现在如何访问存储在用户池中的 Cognito 用户信息。我找不到任何明确的信息,当然也没有代码,显示如何使用 IdentityId 获取 Cognito 用户的属性、用户名等。

看来,如果我在 API Gateway 中使用“Cognito 用户池”来授权我的方法,那么可以使用正文映射模板将 Cognito 用户信息(例如 sub、用户名和电子邮件地址)放入上下文中,但我确实这样做了不获取 IdentityId。

但是如果我使用 AWS_IAM在 API 网关中授权我的方法,然后正文映射模板执行相反的操作 - 它为我提供 IdentityId 但不提供 Cognito 用户字段,例如 sub 和 username 以及电子邮件。

这让我发疯 - 如何将 IdentityId 和所有 Cognito 用户字段和属性合并到一个数据结构中?我似乎只能得到一个或另一个的事实是没有意义的。

最佳答案

事实证明,要使用 AWS Lambda/Cognito/API Gateway 同时获取 IdentityId 和用户详细信息,您需要有一个使用 AWS_IAM 进行身份验证的 Lambda 函数。 (不是 COGNITO_USER_POOLS ),您必须将您的请求发送到 AWS API 网关,但它必须是签名请求,然后您必须修改集成请求正文映射模板,以便在事件中为您提供 IdentityId(可能是上下文?不记得了)。现在您有了 IdentityId。呼。现在您必须从前端向后端提交客户端的 Cognito ID token 。验证 token 很重要 - 如果您不验证它,您就不能相信它没有被篡改。要解码和验证 token ,您必须从用户池中获取 key ,将它们放入您的脚本中,确保您的 AWS lambda zipfile 中包含 jwt 解码库和签名验证库。现在您的脚本必须验证从前端提交的 token ,然后您可以从 token 中获取用户详细信息。瞧!现在您拥有 IdentityId 以及用户详细信息,例如他们的子、用户名和电子邮件地址。太简单。

以上是使用 AWS Cognito/Lambda/API Gateway 获取与 IdentityId 关联的用户名所需的操作。这花了我几天的时间才开始工作。

我可以对任何在此徘徊的亚马逊员工说吗......好吧,获取与 IdentityId 相关联的用户详细信息太难了。你需要解决这个问题。这让我很生气,这太难了,浪费了我太多的时间。

解决方案:

我通过在此处修改 Amazon 员工自定义授权器来做到这一点:
https://s3.amazonaws.com/cup-resources/cup_custom_authorizer_lambda_function_blueprint.zip

如在此处找到和描述的:
https://aws.amazon.com/blogs/mobile/integrating-amazon-cognito-user-pools-with-api-gateway/

use strict';
let util = require('util');

var jwt = require('jsonwebtoken');
var jwkToPem = require('jwk-to-pem');

var userPoolId = 'YOUR USERPOOL ID';
var region = 'YOUR REGION'; //e.g. us-east-1
var iss = 'https://cognito-idp.' + region + '.amazonaws.com/' + userPoolId;

//https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html
// DOWNLOAD FROM https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json
let userPoolKeys = {PUT YOUR DOWNLOADED USER POOL KEYS JSON HERE};
var pems = {};

let convertKeysToPems = () => {
var keys = userPoolKeys['keys'];
for(var i = 0; i < keys.length; i++) {
//Convert each key to PEM
var key_id = keys[i].kid;
var modulus = keys[i].n;
var exponent = keys[i].e;
var key_type = keys[i].kty;
var jwk = { kty: key_type, n: modulus, e: exponent};
var pem = jwkToPem(jwk);
pems[key_id] = pem;
}
}

exports.handler = function(event, context) {

convertKeysToPems()
console.log(event);
let token = event['body-json'].cognitoUserToken;
console.log(event['body-json'].cognitoUserToken);
ValidateToken(pems, event, context, token);

};


let ValidateToken = (pems, event, context, token) => {

//Fail if the token is not jwt
var decodedJwt = jwt.decode(token, {complete: true});
console.log(decodedJwt)
if (!decodedJwt) {
console.log("Not a valid JWT token");
context.fail("Unauthorized");
return;
}

//Fail if token is not from your UserPool
if (decodedJwt.payload.iss != iss) {
console.log("invalid issuer");
context.fail("Unauthorized");
return;
}

//Reject the jwt if it's not an 'Access Token'
if (decodedJwt.payload.token_use != 'id') {
console.log("Not an id token");
context.fail("Unauthorized");
return;
}

//Get the kid from the token and retrieve corresponding PEM
var kid = decodedJwt.header.kid;
var pem = pems[kid];
if (!pem) {
console.log(pems, 'pems');
console.log(kid, 'kid');
console.log('Invalid token');
context.fail("Unauthorized");
return;
}

//Verify the signature of the JWT token to ensure it's really coming from your User Pool

jwt.verify(token, pem, { issuer: iss }, function(err, payload) {
if(err) {
context.fail("Unauthorized");
} else {
let x = decodedJwt.payload
x.identityId = context.identity.cognitoIdentityId
//let x = {'identityId': context['cognito-identity-id'], 'decodedJwt': decodedJwt}
console.log(x);
context.succeed(x);
}
});
}

关于aws-lambda - 带有 Cognito 的 AWS Lambda API 网关 - 如何使用 IdentityId 访问和更新 UserPool 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42386180/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com