How to throw custom error message from API Gateway custom authorizer

纵饮孤独 提交于 2019-12-01 14:00:37

问题


Here in the blue print says, API gateway will respond with 401: Unauthorized.

I wrote the same raise Exception('Unauthorized') in my lambda and was able to test it from Lambda Console. But in POSTMAN, I'm receiving status 500 with body:

{
  message: null`
} 

I want to add custom error messages such as "Invalid signature", "TokenExpired", etc., Any documentation or guidance would be appreciated.


回答1:


This is totally possible but the docs are so bad and confusing.

Here's how you do it:

There is an object called $context.authorizer that you have access to in your gateway responses template. You can read more about it here: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html

Here is an examample of populating this authorizer object from your authorizer lambda like so:

// 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;
        }

They key here is adding this part:

// 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,
        };

This will become available on $context.authorizer

I then set the body mapping template in gateway responses tab like this:

{"message":"$context.authorizer.stringKey"}

NOTE: it must be quoted!

finally - after sending a request in postman with Authorization token set to deny I now get back a payload from postman that looks like this:

{
    "message": "stringval custom anything can go here"
}



回答2:


i use @maxwell solutions, using custom Resource ResponseTemplates. for deny response show like in bellow.

{
  "success":false,
  "message":"Custom Deny Message"
}

you can check this, https://github.com/SeptiyanAndika/serverless-custom-authorizer




回答3:


This can be easily achieved by using the context.fail() function.

Example:

const customAuthorizer: Handler = (event, context: Context, callback: Callback) => {        
    authenticate(event)
        .then((res) => {
            // result should be as described in AWS docs
            callback(null, res);
        })
        .catch((err) => {
            context.fail("Unauthorized");
        });
}

This will return a 401 response with following body.

{
    "message": "Unauthorized"
}

This can also be achieved by throwing an error:

throw new Error('Unauthorized');



回答4:


I'm not sure what is causing the 500 message: null response. Possibly misconfiguration of the Lambda function permissions.

To customize the Unauthorized error response, you'll set up a Gateway Response for the UNAUTHORIZED error type. You can configure response headers and payload here.



来源:https://stackoverflow.com/questions/47921803/how-to-throw-custom-error-message-from-api-gateway-custom-authorizer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!