使用自定义 Lambda Authorizer 时,为什么 API Gateway 会返回内部服务器错误?

问题描述 投票:0回答:1

我有一个

listUsers
功能,可以与认知授权者完美配合。

由于我已将其更改为 Lambda Authorizer,它会返回

500
HTTP 状态代码。

serverless.yml

provider:
    httpApi:
        cors: true
        authorizers:
          customAuthorizer:
            type: request
            functionName: custom-authorizer
functions:
    custom-authorizer:
        handler: authorizer.handler

listUsers:
  handler: src/users/index.listUsersHandler
  events:
    - httpApi:
        path: /users
        method: get
        authorizer: customAuthorizer

authorizer.js

const { CognitoJwtVerifier } = require('aws-jwt-verify');
const Cognito = require('../shared/Cognito');

module.exports.handler = async (event) => {
    const authHeader = event.headers.authorization;
    if (!authHeader) {
        console.log('No auth header');
        return {
            isAuthorized: false,
        };
    }
    const token = authHeader.split(' ')[1];
    console.log(token);
    const verifier = CognitoJwtVerifier.create({
        userPoolId: Cognito.UserPoolId,
        tokenUse: 'access',
        clientId: Cognito.ClientId,
    });
    let payload = null;
    try {
        payload = await verifier.verify(token);
        console.log('Token is valid. Payload:', payload);
        return {
            isAuthorized: true,
        };
    } catch {
        console.log('Token is invalid.');
        return { isAuthorized: false };
    }
};

当我向

/users
发出 GET 请求时,它会正确重定向到我的自定义授权者,并且在日志中我可以看到该令牌是有效的。

但是,它永远不会运行实际的

listUsers
函数,在 Postman 中我得到:

{
    "message": "Internal Server Error"
}
amazon-web-services aws-lambda aws-api-gateway amazon-cognito aws-sdk-js
1个回答
0
投票

Lambda 授权者的预期输出本质上是主体标识符和策略文档:

  • 效果:...
    Allow
    /
    Deny
    API网关执行服务
  • 操作:...调用 (
    execute-api:Invoke
    )
  • 资源:...指定的API方法

您的 Lambda 授权者响应不正确,这就是您收到内部服务器错误的原因:

return {isAuthorized: true};

作为一个很好的起点,使用

methodArn
对象 (
event
) 上的 
event.methodArn
属性作为资源。这是调用者请求的方法的 ARN,由 AWS 提供。

此方法将返回最小但正确的授权者响应:

function generatePolicy(principalId, effect, resource) {
    return {
        principalId,
        policyDocument: {
            Version: '2012-10-17',
            Statement: [{
                Action: 'execute-api:Invoke',
                Effect: effect,
                Resource: resource
            }]
        }
    };
}

用途:

const authHeader = event.headers.authorization;

if (!authHeader) {
    console.log('No auth header');
    return generatePolicy('user', 'Deny', event.methodArn);
}

...

try {
    const payload = await verifier.verify(token);
    return generatePolicy('user', 'Allow', event.methodArn);
} catch {
    return generatePolicy('user', 'Deny', event.methodArn);
}
© www.soinside.com 2019 - 2024. All rights reserved.