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.
The easiest way to set custom HTTP status code is to setup a Lambda Proxy Integration in API Gateway. In API Gateway > Resource > Actions Dropdown > Create Method > tick Lambda Proxy Integration and select appropriate Lambda function. For async functions just return with an object with statusCode and body .
If the API uses a usage plan (the apiKeySource is set to AUTHORIZER ), the Lambda authorizer function must return one of the usage plan's API keys as the usageIdentifierKey property value.
For API Gateway to pass the error type (for example, InvalidParameterException ), as part of the response to the client, the Lambda function must include a header (for example, "X-Amzn-ErrorType":"InvalidParameterException" ) in the headers property.
There is no need to map the Lambda function response to its proper HTTP response. To return the result to the client, set up the integration response to pass the endpoint response through as-is to the corresponding method response. Or you can map the endpoint response data to the method response data.
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" }
I used @maxwell solution, using custom resource ResponseTemplates
. For deny response see below:
{ "success":false, "message":"Custom Deny Message" }
You can check this out here: https://github.com/SeptiyanAndika/serverless-custom-authorizer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With