由于 AWS 中的 CORS 阻止来源而导致访问被拒绝 Api-Gateway
Getting access denied due to origin blocked by CORS in AWS Api-Gateway
我有一个 AWS SAM 模板,它在 API 网关中创建 lambda 函数和 post 方法。默认情况下,它使用 Lambda 代理集成,当我通过 PostMan 工具进行测试时它工作正常,但是当我将 API 网关 URL 与我的沙箱应用程序一起使用时,它显示以下错误。
Access to XMLHttpRequest at 'https://abcdef.execute-api.eu-west-2.amazonaws.com/dev/my-api' from origin 'https://abcd.csb.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
但是当我手动创建 API 网关 post 方法并尝试时它工作正常。
Lambda 函数也在响应中返回以下 header。
response = {
'statusCode': status_code,
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST'
},
'body': json.dumps(response_data)
}
以下是 AWS SAM 模板。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
AWS SAM Template
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 10
Parameters:
DeploymentEnv:
Type: String
Resources:
ApiGatewayApi:
DependsOn: LambdaFunction
Type: AWS::Serverless::Api
Properties:
StageName: !Ref DeploymentEnv
EndpointConfiguration:
Type: REGIONAL
Cors:
AllowMethods: "'POST,OPTIONS'"
AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
AllowOrigin: "'*'"
MaxAge: "'600'"
AllowCredentials: false
Auth:
DefaultAuthorizer: NONE
ApiKeyRequired: true # sets for all methods
LambdaFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
FunctionName: !Join [ "", [ !Ref DeploymentEnv, "-my-lambda"]]
CodeUri: my_api/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Events:
EventTriggerlambda:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
RestApiId: !Ref ApiGatewayApi
Path: /my-api
Method: POST
Auth:
ApiKeyRequired: true
Role: Role_URN
Environment:
Variables:
URI: Test
USER_NAME: Test
PASSWORD: Test
ApiKey:
Type: AWS::ApiGateway::ApiKey
DependsOn: ApiGatewayApiStage
Properties:
Name: !Join ["", [{"Ref": "AWS::StackName"}, "-apikey"]]
Enabled: true
StageKeys:
- RestApiId: !Ref ApiGatewayApi
StageName: !Ref DeploymentEnv
UsagePlan:
DependsOn:
- ApiGatewayApiStage
Type: AWS::ApiGateway::UsagePlan
Properties:
ApiStages:
- ApiId: !Ref ApiGatewayApi
Stage: !Ref DeploymentEnv
Throttle:
BurstLimit: 500
RateLimit: 100
UsagePlanName: MY-UsagePlan
UsagePlanKey:
Type: AWS::ApiGateway::UsagePlanKey
Properties:
KeyId: !Ref ApiKey
KeyType: API_KEY
UsagePlanId: !Ref UsagePlan
Outputs:
LambdaFunction:
Description: "Lambda Function ARN"
Value: !GetAtt LambdaFunction.Arn
请帮忙,谢谢:)
配置不适合在 AWS SAM 模板的 API-Gateway 中创建 API。因为 SAM 部署默认使用 lambda 代理集成,这就是为什么在方法响应中,需要的值很少,无法使用上述配置自动设置。因此,我使用开放 API 规范,其中我定义了 Rest API 配置,部署后无需任何手动干预即可正常工作。
如下配置即可。
ApiGatewayApi:
DependsOn: LambdaFunction
Type: AWS::Serverless::Api
Properties:
StageName: !Ref DeploymentEnv
DefinitionBody:
'Fn::Transform':
Name: 'AWS::Include'
Parameters:
Location: !Join [ '', [ 's3://mybucket', '/openapi-spec.yaml' ] ]
EndpointConfiguration:
Type: REGIONAL
OpenAPI 配置
openapi: "3.0.1"
info:
title: "test-api"
description: "Created by AWS Lambda"
version: "2022-01-07T18:00:40Z"
paths:
/test-api:
post:
responses:
"200":
description: "200 response"
headers:
Access-Control-Allow-Origin:
schema:
type: "string"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
x-amazon-apigateway-integration:
httpMethod: "POST"
uri:
Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
responses:
default:
statusCode: "200"
responseParameters:
method.response.header.Access-Control-Allow-Origin: "'*'"
passthroughBehavior: "when_no_match"
contentHandling: "CONVERT_TO_TEXT"
type: "aws_proxy"
options:
responses:
"200":
description: "200 response"
headers:
Access-Control-Allow-Origin:
schema:
type: "string"
Access-Control-Allow-Methods:
schema:
type: "string"
Access-Control-Allow-Headers:
schema:
type: "string"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
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,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'*'"
requestTemplates:
application/json: "{\"statusCode\": 200}"
passthroughBehavior: "when_no_match"
type: "mock"
x-amazon-apigateway-any-method:
responses:
"200":
description: "200 response"
content: {}
security:
- api_key: []
x-amazon-apigateway-integration:
httpMethod: "POST"
uri: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${LambdaFunction.Arn}/invocations"
responses:
".*":
statusCode: "200"
passthroughBehavior: "when_no_match"
type: "aws_proxy"
components:
schemas:
Empty:
title: "Empty Schema"
type: "object"
securitySchemes:
api_key:
type: "apiKey"
name: "x-api-key"
in: "header"
此处 openapi-spec.yaml 文件保存在与 AWS SAM 模板相同的文件夹中,并在部署开始之前使用 GitHub 工作流管道文件中的以下命令上传到 S3 存储桶.
- run: aws s3 cp openapi-spec.yaml s3://mnai-code-deployments
- run: sam build
- run: sam deploy --no-confirm-changeset --no-fail-on-empty-changeset --stack-name my-stack --s3-bucket mybucket --capabilities CAPABILITY_IAM --region eu-west-2 --parameter-overrides ParameterKey=DeploymentEnv,ParameterValue=dev ParameterKey=S3Bucket,ParameterValue=mybucket
谢谢
我有一个 AWS SAM 模板,它在 API 网关中创建 lambda 函数和 post 方法。默认情况下,它使用 Lambda 代理集成,当我通过 PostMan 工具进行测试时它工作正常,但是当我将 API 网关 URL 与我的沙箱应用程序一起使用时,它显示以下错误。
Access to XMLHttpRequest at 'https://abcdef.execute-api.eu-west-2.amazonaws.com/dev/my-api' from origin 'https://abcd.csb.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
但是当我手动创建 API 网关 post 方法并尝试时它工作正常。
Lambda 函数也在响应中返回以下 header。
response = {
'statusCode': status_code,
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST'
},
'body': json.dumps(response_data)
}
以下是 AWS SAM 模板。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
AWS SAM Template
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 10
Parameters:
DeploymentEnv:
Type: String
Resources:
ApiGatewayApi:
DependsOn: LambdaFunction
Type: AWS::Serverless::Api
Properties:
StageName: !Ref DeploymentEnv
EndpointConfiguration:
Type: REGIONAL
Cors:
AllowMethods: "'POST,OPTIONS'"
AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
AllowOrigin: "'*'"
MaxAge: "'600'"
AllowCredentials: false
Auth:
DefaultAuthorizer: NONE
ApiKeyRequired: true # sets for all methods
LambdaFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
FunctionName: !Join [ "", [ !Ref DeploymentEnv, "-my-lambda"]]
CodeUri: my_api/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Events:
EventTriggerlambda:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
RestApiId: !Ref ApiGatewayApi
Path: /my-api
Method: POST
Auth:
ApiKeyRequired: true
Role: Role_URN
Environment:
Variables:
URI: Test
USER_NAME: Test
PASSWORD: Test
ApiKey:
Type: AWS::ApiGateway::ApiKey
DependsOn: ApiGatewayApiStage
Properties:
Name: !Join ["", [{"Ref": "AWS::StackName"}, "-apikey"]]
Enabled: true
StageKeys:
- RestApiId: !Ref ApiGatewayApi
StageName: !Ref DeploymentEnv
UsagePlan:
DependsOn:
- ApiGatewayApiStage
Type: AWS::ApiGateway::UsagePlan
Properties:
ApiStages:
- ApiId: !Ref ApiGatewayApi
Stage: !Ref DeploymentEnv
Throttle:
BurstLimit: 500
RateLimit: 100
UsagePlanName: MY-UsagePlan
UsagePlanKey:
Type: AWS::ApiGateway::UsagePlanKey
Properties:
KeyId: !Ref ApiKey
KeyType: API_KEY
UsagePlanId: !Ref UsagePlan
Outputs:
LambdaFunction:
Description: "Lambda Function ARN"
Value: !GetAtt LambdaFunction.Arn
请帮忙,谢谢:)
配置不适合在 AWS SAM 模板的 API-Gateway 中创建 API。因为 SAM 部署默认使用 lambda 代理集成,这就是为什么在方法响应中,需要的值很少,无法使用上述配置自动设置。因此,我使用开放 API 规范,其中我定义了 Rest API 配置,部署后无需任何手动干预即可正常工作。
如下配置即可。
ApiGatewayApi:
DependsOn: LambdaFunction
Type: AWS::Serverless::Api
Properties:
StageName: !Ref DeploymentEnv
DefinitionBody:
'Fn::Transform':
Name: 'AWS::Include'
Parameters:
Location: !Join [ '', [ 's3://mybucket', '/openapi-spec.yaml' ] ]
EndpointConfiguration:
Type: REGIONAL
OpenAPI 配置
openapi: "3.0.1"
info:
title: "test-api"
description: "Created by AWS Lambda"
version: "2022-01-07T18:00:40Z"
paths:
/test-api:
post:
responses:
"200":
description: "200 response"
headers:
Access-Control-Allow-Origin:
schema:
type: "string"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
x-amazon-apigateway-integration:
httpMethod: "POST"
uri:
Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
responses:
default:
statusCode: "200"
responseParameters:
method.response.header.Access-Control-Allow-Origin: "'*'"
passthroughBehavior: "when_no_match"
contentHandling: "CONVERT_TO_TEXT"
type: "aws_proxy"
options:
responses:
"200":
description: "200 response"
headers:
Access-Control-Allow-Origin:
schema:
type: "string"
Access-Control-Allow-Methods:
schema:
type: "string"
Access-Control-Allow-Headers:
schema:
type: "string"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
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,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'*'"
requestTemplates:
application/json: "{\"statusCode\": 200}"
passthroughBehavior: "when_no_match"
type: "mock"
x-amazon-apigateway-any-method:
responses:
"200":
description: "200 response"
content: {}
security:
- api_key: []
x-amazon-apigateway-integration:
httpMethod: "POST"
uri: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${LambdaFunction.Arn}/invocations"
responses:
".*":
statusCode: "200"
passthroughBehavior: "when_no_match"
type: "aws_proxy"
components:
schemas:
Empty:
title: "Empty Schema"
type: "object"
securitySchemes:
api_key:
type: "apiKey"
name: "x-api-key"
in: "header"
此处 openapi-spec.yaml 文件保存在与 AWS SAM 模板相同的文件夹中,并在部署开始之前使用 GitHub 工作流管道文件中的以下命令上传到 S3 存储桶.
- run: aws s3 cp openapi-spec.yaml s3://mnai-code-deployments
- run: sam build
- run: sam deploy --no-confirm-changeset --no-fail-on-empty-changeset --stack-name my-stack --s3-bucket mybucket --capabilities CAPABILITY_IAM --region eu-west-2 --parameter-overrides ParameterKey=DeploymentEnv,ParameterValue=dev ParameterKey=S3Bucket,ParameterValue=mybucket
谢谢