如何从API网关自定义授权程序中抛出自定义错误消息

ime*_*emi 14 aws-api-gateway

这里的蓝图说,API网关将与401回应:未经授权.

raise Exception('Unauthorized')在lambda中写了同样的内容,并且可以从Lambda Console中测试它.但是在POSTMAN中,我正在接收500 身体状态:

{
  message: null`
} 
Run Code Online (Sandbox Code Playgroud)

我想添加自定义错误消息,如"无效签名","TokenExpired"等,任何文档或指导将不胜感激.

max*_*ell 12

这是完全可能的,但文档是如此糟糕和混乱.

这是你如何做到的:

有一个对象称为$context.authorizer您可以访问网关响应模板.您可以在此处阅读更多相关信息:https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html

这是authorizer从你的授权者lambda 填充这个对象的例子,如下所示:

// A simple TOKEN authorizer example to demonstrate how to use an authorization token 
// to allow or deny a request. In this example, the caller named 'user' is allowed to invoke 
// a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke 
// the request if the token value is 'deny'. If the token value is 'Unauthorized', the function 
// returns the 'Unauthorized' error with an HTTP status code of 401. For any other token value, 
// the authorizer returns an 'Invalid token' error. 

exports.handler =  function(event, context, callback) {
    var token = event.authorizationToken;
    switch (token.toLowerCase()) {
        case 'allow':
            callback(null, generatePolicy('user', 'Allow', event.methodArn));
            break;
        case 'deny':
            
            callback(null, generatePolicy('user', 'Deny', event.methodArn));
            break;
        case 'unauthorized':
            callback("Unauthorized");   // Return a 401 Unauthorized response
            break;
        default:
            callback("Error: Invalid token"); 
    }
};

       var generatePolicy = function(principalId, effect, resource) {
            var authResponse = {};
            
            authResponse.principalId = principalId;
            if (effect && resource) {
                var policyDocument = {};
                policyDocument.Version = '2012-10-17'; 
                policyDocument.Statement = [];
                var statementOne = {};
                statementOne.Action = 'execute-api:Invoke'; 
                statementOne.Effect = effect;
                statementOne.Resource = resource;
                policyDocument.Statement[0] = statementOne;
                authResponse.policyDocument = policyDocument;
            }
            
            // Optional output with custom properties of the String, Number or Boolean type.
            authResponse.context = {
                "stringKey": "stringval custom anything can go here",
                "numberKey": 123,
                "booleanKey": true,
            };
            return authResponse;
        }
Run Code Online (Sandbox Code Playgroud)

他们关键的是添加这部分:

// Optional output with custom properties of the String, Number or Boolean type.

        authResponse.context = {
            "stringKey": "stringval custom anything can go here",
            "numberKey": 123,
            "booleanKey": true,
        };
Run Code Online (Sandbox Code Playgroud)

这将在$ context.authorizer上提供

然后我在网关响应选项卡中设置了身体映射模板,如下所示:

{"message":"$context.authorizer.stringKey"}
Run Code Online (Sandbox Code Playgroud)

注意:必须引用它!

最后 - 在邮递员发送带有Authorization令牌设置的请求后拒绝我现在从邮递员那里拿回一个看起来像这样的有效载荷:

{
    "message": "stringval custom anything can go here"
}
Run Code Online (Sandbox Code Playgroud)

  • 您应该记住,网关响应仅在您重新部署 API 后应用。您还可以使用 `Response Headers` 而不是编辑默认的 `Body Mapping Template` 来保留全局 403 错误以返回正确的错误消息正文。 (3认同)
  • 如果我从授权者内部抛出一个错误,例如“抛出新错误(“blabla”)”,为什么错误消息不是“{message:“blabla”}”?如果没有这样的行为,我们就无法发送带有 500 状态代码的自定义错误消息。 (3认同)
  • 注意:这似乎仅适用于 403“访问被拒绝”网关响应。我仍然没有找到将上下文传递给 401“未经授权”网关响应的方法。这只能由不接收授权者上下文的回调(“未经授权”)触发。这似乎是 AWS 的一个巨大限制。 (3认同)

小智 5

我使用了@maxwell 解决方案,使用了自定义资源ResponseTemplates。对于拒绝响应,请参见下文:

{
  "success":false,
  "message":"Custom Deny Message"
}
Run Code Online (Sandbox Code Playgroud)

你可以在这里查看:https : //github.com/SeptiyanAndika/serverless-custom-authorizer


Jac*_*AWS 2

我不确定是什么导致了 500message: null响应。可能是 Lambda 函数权限配置错误。

要自定义未经授权的错误响应,您需要为错误类型设置网关响应UNAUTHORIZED。您可以在此处配置响应标头和负载。

  • 由于原始发布者引发了原始“Exception”,因此 lambda 授权函数出错,这意味着它返回 500 错误。在 API Gateway 中,这会触发 `Authorizer Failure` 网关响应,该响应具有默认模板 `{"message":$context.error.messageString}`。由于 lambda “crashed” 为空,因此该键的默认值是 {"message":null}。从未设置过“$context.error.messageString”属性。 (2认同)