AWS Serverless how to fix CORS for custom lambda authorizer
When added a custom AWS Lambda Authorizer to your Serverless configuration you might notice that on the front-end when a user is unauthorized they get a CORS error. To understand how this works we need to understand how CORS work for the regular requests first.
When specifying a cors
flag in the config like it’s shown below, this only sets the CORS headers for the so-called preflight requests. Those are OPTIONS requests that browsers make before actual requests. They do so to verify that an endpoint on a different origin (domain) can actually be processed.
functions:
get-educations:
handler: bin/get-educations
events:
- http:
path: /educations
method: get
cors: true
When this flag is set to true
browser receives additional headers on OPTIONS requests and therefore not complains about CORS.
However, to fix the CORS for the regular responses we need to set the headers in the response from a Lambda function. That’s pretty trivial — just add the headers into the response object.
return Response{
...
Headers: map[string]string{
...
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
},
}, nil
When it comes to a custom Lambda authorizer it works in a different way. If it returns an “Allow” policy the underlying Lambda function is executed and the previously mentioned algorithm works. However, when it throws an error or returns a “Deny” policy this means that the protected function is not executed. Furthermore, in the authorizer handler we don’t have any headers to work with in the return object. So, how do we solve it?
For this we will need to create an API Gateway Response which will adjust response headers to our needs. In order to do so we need to specify the following config in serverless.yml
resources:
Resources:
Unauthorized:
Type: AWS::ApiGateway::GatewayResponse
Properties:
ResponseParameters:
"gatewayresponse.header.Access-Control-Allow-Origin": "'*'"
"gatewayresponse.header.Access-Control-Allow-Headers": "'*'"
ResponseType: "DEFAULT_4XX"
RestApiId:
Ref: "ApiGatewayRestApi"
Here in ResponseType: "DEFAULT_4XX"
we tell the ApiGateway that this will apply to all responses with status codes starting with 4.
ResponseParameters
specify the headers we want to add. Notice the single quotes inside the double quotes. This is not a typo but a required syntax for the wildcard to work.
We don’t need to refer to this resource in our functions. Defining in the resources will be just enough. A resulting config might look like this
After updating the configuration there won’t be any CORS issues with the authorizer responses anymore.