bref
bref copied to clipboard
Document dealing with CORS
I am opening this issue so that we document this information.
When building an API on Lambda (+ API Gateway) we often need to enable CORS so that it can be called from the browser (e.g. with a SPA).
There is a very simple option in SAM (in template.yaml
) to do that:
Globals:
Api:
Cors: "'*'"
However it doesn't work with sam local
yet! (it works when deployed though)
The issue to track that in the SAM repository: https://github.com/awslabs/aws-sam-cli/issues/323 There is a pull request as well: https://github.com/awslabs/aws-sam-cli/pull/1009
Workaround
A workaround is to deal with CORS in the PHP API.
Here is an example for a Slim application:
composer require eko3alpha/slim-cors-middleware
$app = new \Slim\App();
$app->add(new \Eko3alpha\Slim\Middleware\CorsMiddleware([
'*' => ['GET', 'POST'],
]));
// ...
UPDATE: That PR (awslabs/aws-sam-cli#1009) mentioned above was closed and the work in progress related to CORS is living here awslabs/aws-sam-cli#1242
With serverless.yml
it seems even simpler: https://serverless.com/framework/docs/providers/aws/events/apigateway/#enabling-cors
functions:
hello:
handler: index.php
layers:
- ${bref:layer.php-73-fpm}
events:
- http:
path: '/'
method: ANY
cors: true
Can you provide also an example of serverless.yml using httpAPI?
Can you provide also an example of serverless.yml using httpAPI?
https://www.serverless.com/framework/docs/providers/aws/events/http-api/#cors-setup
Short version:
provider:
httpApi:
cors: true
If anyone wants to add that to the Bref documentation that would be neat.
Hi @mnapoli
I'm using Api Gateway v2 (httpApi) created externally (via Terraform). When I try to add cors via provider section (like in the example above) I'm getting an error from the Serverless framework:
Cannot setup CORS rules for externally configured HTTP API
That's ok, I can configure CORS via Terraform too. That's the Terraform block I added:
resource "aws_apigatewayv2_api" "public" {
name = "${var.environment}-api"
protocol_type = "HTTP"
description = "Public API Gateway"
cors_configuration {
allow_origins = [
"*"
]
allow_headers = [
"Content-Type",
"X-Amz-Date",
"Authorization",
"X-Api-Key",
"X-Amz-Security-Token",
"X-Amz-User-Agent"
]
allow_methods = [
"OPTIONS",
"HEAD",
"GET",
"POST",
"PUT",
"PATCH",
"DELETE"
]
}
}
Now - for some reason requests from the browser to the API Gateway still don't work due to CORS issue. Question - do I need to add additional CORS headers manually/explicitly in the PHP code that returns PSR7 response object? I made the CURL request to the endpoint and it seems API Gateway doesn't add any CORS headers automatically.
I have no idea if that's the right configuration for Terraform. With the config in serverless.yml
you don't need to add any header.
More generally, for support questions I'd say it's best to ask in GitHub discussions: https://github.com/brefphp/bref/discussions
Thanks, I solved the issue. So you can configure CORS headers via Terraform in the way I did. The issue is that HTTP API Gateway doesn't add CORS headers to the response automatically if you don't add specific headers to your request (very important if you're testing your API with e.g. curl). I started calling my API with extra headers like that:
curl -v https://xxxxxx.execute-api.eu-west-1.amazonaws.com/test/api/installation/XXXXX -H 'Origin:http://example.com' -H 'Access-Control-Request-Method: GET'
instead of just
curl -v https://xxxxxx.execute-api.eu-west-1.amazonaws.com/test/api/installation/XXXXX
and suddenly API GW started adding cors headers. Hope this will be useful for some people.