如何通过SAM或CLI配置ApiGateway同步调用的CORS?
解决SAM部署同步Step Functions时的CORS配置问题
一、SAM便捷配置方式
如果使用SAM的AWS::Serverless::Api资源,可以直接在该资源的CorsConfiguration中指定允许的请求方法(包含POST、PATCH)及其他CORS规则,SAM会自动生成对应的OPTIONS方法和响应头配置,无需手动编写预检请求逻辑。
以下是完整的SAM模板片段:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Resources: # 同步执行的Step Functions状态机 SyncStateMachine: Type: AWS::Serverless::StateMachine Properties: DefinitionUri: statemachine/workflow.asl.json Policies: - StatesExecutionPolicy: StateMachineName: !Ref SyncStateMachine # 配置带CORS规则的API Gateway SyncApi: Type: AWS::Serverless::Api Properties: StageName: prod CorsConfiguration: AllowOrigins: ["https://your-frontend-domain.com"] # 替换为实际前端域名,测试用可改为"*" AllowMethods: ["POST", "PATCH", "OPTIONS"] AllowHeaders: ["Content-Type", "X-Amz-Date", "Authorization", "X-Api-Key"] ExposeHeaders: ["X-Amzn-Trace-Id"] # POST方法关联StartSyncExecution集成 PostSyncIntegration: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref SyncApi ResourceId: !GetAtt SyncApi.RootResourceId HttpMethod: POST AuthorizationType: NONE # 根据认证需求调整,比如AWS_IAM Integration: Type: AWS IntegrationHttpMethod: POST Uri: !Sub arn:aws:apigateway:${AWS::Region}:states:action/StartSyncExecution Credentials: !GetAtt ApiGatewaySyncRole.Arn RequestTemplates: application/json: | { "input": "$input.json('$')", "stateMachineArn": "${SyncStateMachine}" } IntegrationResponses: - StatusCode: 200 ResponseTemplates: application/json: "$input.json('$')" ResponseParameters: method.response.header.Access-Control-Allow-Origin: "'https://your-frontend-domain.com'" method.response.header.Access-Control-Allow-Methods: "'POST, PATCH, OPTIONS'" method.response.header.Access-Control-Allow-Headers: "'Content-Type, X-Amz-Date, Authorization, X-Api-Key'" MethodResponses: - StatusCode: 200 ResponseParameters: method.response.header.Access-Control-Allow-Origin: true method.response.header.Access-Control-Allow-Methods: true method.response.header.Access-Control-Allow-Headers: true # PATCH方法关联StartSyncExecution集成(逻辑与POST一致) PatchSyncIntegration: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref SyncApi ResourceId: !GetAtt SyncApi.RootResourceId HttpMethod: PATCH AuthorizationType: NONE Integration: Type: AWS IntegrationHttpMethod: POST Uri: !Sub arn:aws:apigateway:${AWS::Region}:states:action/StartSyncExecution Credentials: !GetAtt ApiGatewaySyncRole.Arn RequestTemplates: application/json: | { "input": "$input.json('$')", "stateMachineArn": "${SyncStateMachine}" } IntegrationResponses: - StatusCode: 200 ResponseTemplates: application/json: "$input.json('$')" ResponseParameters: method.response.header.Access-Control-Allow-Origin: "'https://your-frontend-domain.com'" method.response.header.Access-Control-Allow-Methods: "'POST, PATCH, OPTIONS'" method.response.header.Access-Control-Allow-Headers: "'Content-Type, X-Amz-Date, Authorization, X-Api-Key'" MethodResponses: - StatusCode: 200 ResponseParameters: method.response.header.Access-Control-Allow-Origin: true method.response.header.Access-Control-Allow-Methods: true method.response.header.Access-Control-Allow-Headers: true # API Gateway调用Step Functions的授权角色 ApiGatewaySyncRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: apigateway.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: StartSyncExecutionAccess PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: states:StartSyncExecution Resource: !Ref SyncStateMachine
二、手动API Gateway资源配置(精细控制场景)
如果需要更灵活的路径或权限配置,可以直接使用AWS::ApiGateway::Resource和AWS::ApiGateway::Method定义资源,并手动配置OPTIONS预检请求:
# 自定义API资源路径(比如/workflow) WorkflowResource: Type: AWS::ApiGateway::Resource Properties: ParentId: !GetAtt SyncApi.RootResourceId PathPart: workflow RestApiId: !Ref SyncApi # OPTIONS方法处理CORS预检 CorsOptionsMethod: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref SyncApi ResourceId: !Ref WorkflowResource HttpMethod: OPTIONS AuthorizationType: NONE Integration: Type: MOCK IntegrationResponses: - StatusCode: 200 ResponseParameters: method.response.header.Access-Control-Allow-Origin: "'https://your-frontend-domain.com'" method.response.header.Access-Control-Allow-Methods: "'POST, PATCH, OPTIONS'" method.response.header.Access-Control-Allow-Headers: "'Content-Type, X-Amz-Date, Authorization, X-Api-Key'" ResponseTemplates: application/json: "" PassthroughBehavior: WHEN_NO_MATCH RequestTemplates: application/json: '{"statusCode": 200}' MethodResponses: - StatusCode: 200 ResponseParameters: method.response.header.Access-Control-Allow-Origin: true method.response.header.Access-Control-Allow-Methods: true method.response.header.Access-Control-Allow-Headers: true # POST方法关联StartSyncExecution(PATCH方法逻辑一致) PostWorkflowMethod: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref SyncApi ResourceId: !Ref WorkflowResource HttpMethod: POST AuthorizationType: NONE Integration: Type: AWS IntegrationHttpMethod: POST Uri: !Sub arn:aws:apigateway:${AWS::Region}:states:action/StartSyncExecution Credentials: !GetAtt ApiGatewaySyncRole.Arn RequestTemplates: application/json: | { "input": "$input.json('$')", "stateMachineArn": "${SyncStateMachine}" } IntegrationResponses: - StatusCode: 200 ResponseParameters: method.response.header.Access-Control-Allow-Origin: "'https://your-frontend-domain.com'" method.response.header.Access-Control-Allow-Methods: "'POST, PATCH, OPTIONS'" method.response.header.Access-Control-Allow-Headers: "'Content-Type, X-Amz-Date, Authorization, X-Api-Key'" ResponseTemplates: application/json: "$input.json('$')" MethodResponses: - StatusCode: 200 ResponseParameters: method.response.header.Access-Control-Allow-Origin: true method.response.header.Access-Control-Allow-Methods: true method.response.header.Access-Control-Allow-Headers: true
关键注意事项
- 确保
ApiGatewaySyncRole拥有states:StartSyncExecution权限,否则API Gateway无法触发同步执行。 - 若之前通过CLI修改过API Gateway配置,建议将所有配置迁移到SAM模板中,避免CI/CD过程中出现配置冲突。
- 生产环境不要使用
AllowOrigins: ["*"],需指定具体的前端域名,降低安全风险。
内容的提问来源于stack exchange,提问作者Math.Random
相关产品推荐
相关产品推荐

