Artemiy Davydov
03/15/2022, 1:49 PMimport * as sst from "@serverless-stack/resources";
import { TableFieldType } from "@serverless-stack/resources";
import path from "path";
import { CorsHttpMethod } from "@aws-cdk/aws-apigatewayv2-alpha";
export default class CoreStack extends sst.Stack {
constructor(scope: <http://sst.App|sst.App>, id: string, props?: sst.StackProps) {
super(scope, id, props);
const usersTable = new sst.Table(this, "UsersTable", {
fields: {
email: TableFieldType.STRING,
},
primaryIndex: { partitionKey: "email" },
});
const linksTable = new sst.Table(this, "LinksTable", {
fields: {
id: TableFieldType.STRING,
},
primaryIndex: { partitionKey: "id" },
});
const webStatic = new sst.ReactStaticSite(this, "WebStatic", {
path: path.resolve(__dirname, "../../frontend"),
cfDistribution: {
comment: "Distribution for React website",
},
});
const api = new sst.Api(this, "Api", {
defaultAuthorizationType: sst.ApiAuthorizationType.AWS_IAM,
cors: {
allowHeaders: ["Authorization", "Content-Type"],
allowMethods: [CorsHttpMethod.ANY],
allowOrigins: ["<http://localhost:3000>", webStatic.url],
allowCredentials: true,
},
defaultFunctionProps: {
// See /esbuild.js. This is necessary to support decorators
bundle: {
esbuildConfig: {
plugins: "esbuild-decorators-plugin.js",
},
},
environment: {
GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID || "",
GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET || "",
USERS_TABLE_NAME: usersTable.tableName,
LINKS_TABLE_NAME: linksTable.tableName,
},
permissions: [usersTable, linksTable],
},
routes: {
"GET /{id}": "src/functions/_id/get/handler.main",
"DELETE /links/{id}": "src/functions/links/_id/delete/handler.main",
"GET /links/{id}": "src/functions/links/_id/get/handler.main",
"PUT /links/{id}": "src/functions/links/_id/put/handler.main",
"POST /links/create": "src/functions/links/create/handler.main",
"GET /links/list": "src/functions/links/list/handler.main",
"GET /users/authRedirect":
"src/functions/users/authRedirect/handler.main",
"GET /users/me": "src/functions/users/me/handler.main",
},
});
this.addDefaultFunctionEnv({
FRONTEND_URL: webStatic.url,
API_URL: api.url,
});
this.addOutputs({
ApiEndpoint: api.url,
WebEndpoint: webStatic.url,
});
}
}
But I still have this in response headers:
access-control-allow-origin: *
Tell me, please, how do you configure CORS?Arpad
03/15/2022, 3:11 PMArtemiy Davydov
03/15/2022, 3:32 PMArpad
03/15/2022, 3:33 PMFrank
Frank
const api = new sst.Api(this, "Api", {
cors: {
allowHeaders: ["Authorization", "Content-Type"],
allowOrigins: ["<http://localhost:3000>"],
allowCredentials: true,
},
...
});
Frank
sst build
, and checked the CloudFormation template in .build/cdk.out
, I see an AWS::ApiGatewayV2::Api
block that looks like this
"ApiCD79AAA0": {
"Type": "AWS::ApiGatewayV2::Api",
"Properties": {
"CorsConfiguration": {
"AllowCredentials": true,
"AllowHeaders": [
"Authorization",
"Content-Type"
],
"AllowOrigins": [
"<http://localhost:3000>"
]
},
...
}
},
Frank
CorsConfiguration
set according to your cors
setting in SST.Frank
Artemiy Davydov
03/16/2022, 12:01 AM"ApiCD79AAA0": {
"Type": "AWS::ApiGatewayV2::Api",
"Properties": {
"CorsConfiguration": {
"AllowCredentials": true,
"AllowHeaders": [
"Authorization",
"Content-Type"
],
"AllowMethods": [
"*"
],
"AllowOrigins": [
"<http://localhost:3000>",
{
"Fn::Join": [
"",
[
"https://",
{
"Fn::GetAtt": [
"WebStaticDistribution81BBDC61",
"DomainName"
]
}
]
]
}
]
},
Artemiy Davydov
03/16/2022, 12:08 AMFrank
CORS
on Api
, it’s automatically adding an OPTION
route with the correct CORS response headers.Frank
Frank