Repository navigation
Description
Full disclosure, this is my first attempt at working with a SAM template so it's likely I'm doing something wrong, but I can't get CORS working for the life of me. My functions work when I hit the endpoints using Insomnia, but when trying to hit it from my app, I get a 404 on the options request. Also, when I run sam local start-api, I get a message saying WARNING: Could not find function for [OPTIONS] to /login resource right above a message saying Mounting index.login (nodejs6.10) at http://127.0.0.1:3000/login [POST]
Below is my template.yaml. I attempted to follow the example here, but still no luck.
However, if I remove the "options" part of the swagger definition, I don't get the OPTIONS warning.
options:
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: 200 response
headers:
Access-Control-Allow-Origin:
type: string
Access-Control-Allow-Methods:
type: string
Access-Control-Allow-Headers:
type: string
x-amazon-apigateway-integration:
responses:
default:
statusCode: 200
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'*'"
passthroughBehavior: when_no_match
requestTemplates:
application/json: "{\"statusCode\": 200}"
type: mock
Any help / suggestions would be greatly appreciated
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Parameters:
TableName:
Default: <TableName>
Type: String
FunctionNamePrefix:
Default: <TableName>
Type: String
Secret:
Default: ""
Type: String
AppConfigReadCapacity:
Default: 5
Type: Number
AppConfigWriteCapacity:
Default: 5
Type: Number
AppConfigPrimaryKey:
Default: id
Type: String
Env:
Default: dev
Type: String
S3Bucket:
Default: <S3Bucket>
Type: String
Resources:
EnterpriseApi:
Type: AWS::Serverless::Api
Properties:
StageName: dev
DefinitionBody:
swagger: '2.0'
info:
title: 'API Gateway Endpoints'
basePath: '/dev'
schemes:
- 'https'
paths:
"/login":
post:
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri: "arn:aws:apigateway:${awsRegion}lambda:path/2015-03-31/functions/arn:aws:lambda:${awsRegion}l:${awsAccount}:function:${function}/invocations"
responses: {}
passthroughBehavior: when_no_match
options:
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: 200 response
headers:
Access-Control-Allow-Origin:
type: string
Access-Control-Allow-Methods:
type: string
Access-Control-Allow-Headers:
type: string
x-amazon-apigateway-integration:
responses:
default:
statusCode: 200
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'*'"
passthroughBehavior: when_no_match
requestTemplates:
application/json: "{\"statusCode\": 200}"
type: mock
LoginFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.login
Runtime: nodejs6.10
CodeUri: 's3://${s3Bucket}/${s3Folder}/test.zip'
FunctionName:
Fn::Join:
- "-"
-
- Ref: FunctionNamePrefix
- login
Description: ''
Timeout: 30
Environment:
Variables:
TABLE_NAME:
Ref: TableName
NODE_ENV:
Ref: Env
S3_BUCKET: <BucketName>
SECRET:
Ref: Secret
AWS_PROFILE:
Ref: AwsProfile
POSTGRES_HOST:
Ref: PostgresHost
POSTGRES_DB:
Ref: PostgresDb
POSTGRES_USER:
Ref: PostgresUser
POSTGRES_PASSWORD:
Ref: PostgresPassword
POSTGRES_DB:
Ref: PostgresDb
API_Key:
Ref: ApiKey
Events:
LoginResource:
Type: Api
Properties:
Path: /login
Method: post
RestApiId:
Ref: EnterpriseApi
Activity
michaelj-smith commentedon Mar 12, 2018
Your options block looks pretty good. I've got a just a few differences, most notably that you don't have a "responseTemplates" property inside the default response, and you don't have the httpMethod property.
The above config is just to get the options endpoint executing in a deployed SAM app. Local execution is a different beast. SAM Local doesn't yet create endpoints for "mock" integration requests. So I've gotten around this by creating an extra Lambda function for local CORS requests:
Also, once you get the OPTIONS endpoint working, your Lambda function for each endpoint needs to return the "Access-Control-Allow-Origin" header on every response. I've made that header a standard part of the response object from every lambda function.
michaelj-smith commentedon Mar 12, 2018
And here's the content of corsOptions.js:
walkerlangley commentedon Mar 13, 2018
Thanks for the detailed response @michaelj-smith. I'll take a look at this tomorrow. Seems like a lot of work to allow testing locally :)
This weekend I ended up moving everything over to serverless and got things working pretty easily (that
cors: trueis pretty nice) but I'm interested to see if I can get things working with sam-local as well.michaelj-smith commentedon Mar 13, 2018
Your welcome. Sorry to hear you couldn't get it working yet.
I agree that there are some less-than-ideal workarounds needed for SAM Local, but it's still a very new tool. I'm impressed at the active development and general responsiveness to such a wide variety of use cases used by the tool. I recently made the switch to SAM from serverless.com framework, because of the power of all of the CloudFormation tools. Still, SAM might not yet be a full solution for everyone.
There was a big release to the SAM tools today (v1.4.0): https://github.com/awslabs/serverless-application-model/releases/tag/1.4.0
This will undoubtedly help unblock the ability for SAM Local developers to start supporting CORS in a future release of SAM Local.
walkerlangley commentedon Mar 13, 2018
@michaelj-smith no worries. I'm sure the tool will evolve. Thanks for the link to the new SAM tools and thanks again for all the help.
walkerlangley commentedon Mar 13, 2018
@michaelj-smith Hate to bother you again, but I feel like I'm so close....
I got the options to return a 200 (huge thanks), however the follow-up POST isn't being sent. Here is my updated template.yml (and I added the corsOptions.js file you added above.) Any ideas what's causing the request to hang?
walkerlangley commentedon Mar 13, 2018
Ok. I got it sorted out.
Thanks again for the help!
snavarro89 commentedon Mar 22, 2018
walkerlangley, how did you got it sorted out?
walkerlangley commentedon Apr 16, 2018
@snavarro89 Sorry, just seeing this. To be honest I forgot what I did at the time to fix this. Are you having any issues?
[-]Any suggestions for CORS besides use serverless.com[/-][+][Feature Request] CORS Support in start-api[/+]jfuss commentedon May 12, 2018
Updated description to '[Feature Request] CORS Support in start-api' and adding labels.
rabowskyb commentedon May 28, 2018
Just in case it might be of some use, here's an example of SAM with CORS enabled: https://github.com/aws-samples/startup-kit-serverless-workload.
24 remaining items
jfuss commentedon Sep 16, 2019
Release in v0.21.0.
Closing
michaelj-smith commentedon Oct 31, 2019
Thank you! I've confirmed that this works great locally in the new versions!
klanthier commentedon Nov 6, 2019
Just wanted to let others know that you can now correctly use start-api with CORS settings like so :
This works for me with the latest version (0.30 as of writing)
franbueno commentedon Dec 20, 2019
Same issue on version 0.38.0 😓
cesarho commentedon Jan 5, 2020
I hit the same error. The server return http 200 without Cors headers. Is there any hint on how to get it passed?
SAM CLI, version 0.39.0
2020-01-05 21:40:19 127.0.0.1 - - [05/Jan/2020 21:40:19] "OPTIONS /orders/193061421222 HTTP/1.1" 200 -
walkerlangley commentedon Jan 13, 2020
I had this working by setting up a "corsHandler" that just returned a status code of 200, but that doesn't seem to be working anymore and neither does adding a Cors "section" in the AWS Sam Template. Any ideas? Cors section of template is below. I also still have the CORS Options handler set up but that doesn't seem to be called (I'm logging before returning the code but the logs aren't printing).
Update: it looks like the issue is the AllowCredentials property isn't setting the Access-Control-Allow-Credentials header to true and I'm getting an error saying it's value is ''.
The Cors response is returning a 200 with
sam--version = 0.40.0
imoby commentedon Feb 14, 2020
I'm having the same issue here, can we open this up again
jakebrinkmann commentedon Mar 11, 2020
The answer by @klanthier worked for me and added these headers:
Merge CDK support into the cdk-support branch (#337)
dmr07 commentedon Nov 8, 2021
Solution from @klanthier appears to no longer work with sam version 1.34.1. @jfuss could this issue be re-opened?
towfiqi commentedon Nov 21, 2021
Not working anymore...
i-am-mani commentedon Dec 25, 2021
Unable to get sam-cli's
start-apiworking locally without CORS. This feature is pretty critical for testing integrations locally.emmanuelnk commentedon Jun 3, 2022
Only the
npm install local-cors-proxysolution worked for me. Every other solution did NOT work unfortunately