AWS Api网关根据 id_token 解析 Cognito 用户池 JWT ,以验证用户的身份。但是,当Cognito通过id_token参数传递#时,AWS Api网关无法正确解析JWT,导致身份验证失败。
解决方法是使用自定义授权Lambda函数来解决此问题。自定义授权Lambda函数负责验证用户的身份并生成API网关策略,以控制对API资源的访问。以下是使用自定义授权Lambda函数的代码示例:
exports.handler = function(event, context, callback) {
// validate JWT token
var idToken = event.authorizationToken.split(' ')[1];
verifyToken(idToken, function(err, token) {
if (err) {
console.log("Failed to authenticate user: ", err);
callback("Unauthorized");
} else {
console.log("User authenticated by Cognito: ", token);
// generate policy to allow access
var authResponse = {
principalId: token.sub,
policyDocument: {
Version: '2012-10-17',
Statement: [{
Action: 'execute-api:Invoke',
Effect: 'Allow',
Resource: event.methodArn
}]
},
context: {
user: JSON.stringify(token)
}
};
callback(null, authResponse);
}
});
function verifyToken(token, done) {
// decode the token
var decoded = jwt.decode(token, {complete: true});
// get the kid from the headers prior to verification
var kid = decoded.header.kid;
// GET the public key from Cognito
request({
url: `https://cognito-idp.${process.env.AWS_REGION}.amazonaws.com/${process.env.USER_POOL_ID}/.well-known/jwks.json`,
json: true
}, function(error, response, body) {
if (!error && response.statusCode === 200) {
var keys = body['keys'];
// search for the kid in the downloaded public keys
var keyIndex = -1;
for (var i=0; i