事实证明,要使用 AWS Lambda/Cognito/API Gateway 同时获取 IdentityId 和用户详细信息,您需要有一个使用 AWS_IAM(不是 COGNITO_USER_POOLS)进行身份验证的 Lambda 函数,您必须将您的请求发送到 AWS API Gateway,但它必须是签名请求,然后您必须修改集成请求正文映射模板,以便在事件中为您提供 IdentityId(可能是上下文?不记得了)。现在您有了 IdentityId。呸。现在您必须将客户端的 Cognito ID 令牌从前端提交到后端。验证令牌很重要——如果你不验证它,你就不能相信它没有被篡改。要解码和验证令牌,您必须从用户池中获取密钥,将它们放入脚本中,确保您的 AWS lambda zip 文件中包含 jwt 解码库和签名验证库。现在您的脚本必须验证从前端提交的令牌,然后您可以从令牌中获取用户详细信息。瞧!现在您拥有 IdentityId 和用户详细信息,例如他们的子用户、用户名和电子邮件地址。很简单。
以上是使用 AWS Cognito/Lambda/API Gateway 获取与 IdentityId 关联的用户名所需的内容。这花了我几天的时间才能开始工作。
我能否对任何徘徊于此的亚马逊员工说......你需要解决这个问题。这让我很生气,因为这太难了,而且浪费了我这么多时间。
解决办法:
我通过在此处修改亚马逊员工的自定义授权人来做到这一点:
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);
}
});
}