如何配置CF来解决此问题?
答案 0 :(得分:51)
直到API网关(APIG)通过其内部使用CloudFormation(CF)支持边缘缓存,我提出了一种解决方法。
你确实可以把CF dist放在APIG面前,诀窍是只强制使用HTTPS"查看器协议策略"并且 NOT 转发HOST标头,因为APIG需要SNI。
我设置了我的CF"默认缓存行为设置"不转发任何标题,强制"查看器协议政策"到"仅限HTTPS;"它的工作原理。希望这有助于其他人。
这是一个具有所有必需配置的CloudFormation资源对象(注意:我对StackName使用约定<stage>--<app name>
):
CloudFront:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
IPV6Enabled: true
HttpVersion: http2
Comment: !Join [ '--', [!Ref 'AWS::StackName', ' Cloud Front']]
Aliases: [!Ref CloudFrontCname]
ViewerCertificate:
AcmCertificateArn: !Ref AcmCertificateArn
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1.1_2016
Origins:
- Id: APIGOrigin
DomainName: !Sub
- ${apigId}.execute-api.${AWS::Region}.amazonaws.com
- { apigId: !Ref ApiGatewayLambdaProxy }
OriginPath: !Sub
- /${Stage}
- { Stage: !Select [ "0", !Split [ '--', !Ref 'AWS::StackName' ] ] }
CustomOriginConfig:
# HTTPPort: 80
HTTPSPort: 443
OriginProtocolPolicy: https-only
OriginCustomHeaders:
- HeaderName: 'Verify-From-Cf'
HeaderValue: !Ref VerifyFromCfHeaderVal
DefaultCacheBehavior:
AllowedMethods: ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
CachedMethods: ["GET", "HEAD", "OPTIONS"]
ForwardedValues:
Headers:
- Access-Control-Request-Headers
- Access-Control-Request-Method
- Origin
- Authorization
# - Host APIG needs to use SNI
QueryString: true
TargetOriginId: APIGOrigin
ViewerProtocolPolicy: https-only
Compress: true
DefaultTTL: 0
CustomErrorResponses:
- ErrorCachingMinTTL: 0
ErrorCode: 400
- ErrorCachingMinTTL: 1
ErrorCode: 403
- ErrorCachingMinTTL: 5
ErrorCode: 500
DNSARecord:
Type: AWS::Route53::RecordSet
Properties:
Comment: !Ref 'AWS::StackName'
Name: !Ref CloudFrontCname
Type: A
HostedZoneName: !Join ['.', [ !Select [1, !Split ['.', !Ref CloudFrontCname]], !Select [2, !Split ['.', !Ref CloudFrontCname]], '']]
AliasTarget:
HostedZoneId: !Ref Route53HostedZoneId
DNSName: !GetAtt CloudFront.DomainName
DNSAAAARecord:
Type: AWS::Route53::RecordSet
Properties:
Comment: !Ref 'AWS::StackName'
Name: !Ref CloudFrontCname
Type: AAAA
HostedZoneName: !Join ['.', [ !Select [1, !Split ['.', !Ref CloudFrontCname]], !Select [2, !Split ['.', !Ref CloudFrontCname]], '']]
AliasTarget:
HostedZoneId: !Ref Route53HostedZoneId
DNSName: !GetAtt CloudFront.DomainName
2018年末更新
MinimumProtocolVersion: TLSv1.1_2016
答案 1 :(得分:4)
添加到以前的答案:
重要的是,行为路径模式实际上应与“真实”路径匹配。
如果API端点为<id>.execute-api.<region>.amazonaws.com/stage-name/my-api
原始域+路径为<id>.execute-api.<region>.amazonaws.com/stage-name
行为路径模式必须为 my-api
,my-api/*
,my-api/something
等
我不知道为什么,但是我认为路径模式可以用作别名,例如:
https://www.example.com/random-name(路径模式random-name
)解析为原始域中设置的域+路径,例如<id>.execute-api.<region>.amazonaws.com/stage-name
。
不是这样。
答案 2 :(得分:2)
如果API Gateway返回403错误:
授权标题需要&#39;凭据&#39;参数。授权 标题需要&#39;签名&#39;参数。授权标头需要 &#39; SignedHeaders&#39;参数。授权标头需要存在 要么是&#39; X-Amz-Date&#39;或者日期&#39;报头中。
也可能是原点端点不正确。 &#34; API Gateway将所有错误视为不存在的路径,因为403权限被拒绝错误而不是404未找到错误。&#34; (见this support thread)。
我收到此错误并假设我错误地转发了Authorization标头,但我只是错误配置了原始路径。
答案 3 :(得分:2)
对于那些正在遵循AWS高级支持知识中心的指南的人,我只想在这里重申
如何使用自己的CloudFront发行版设置API网关? https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-cloudfront-distribution/
如果您使用AWS控制台设置CloudFront分配,则根本原因是将基于所选请求标头的缓存设置为全部。
将其设置为“无”或排除白名单中的Host
标头将解决此问题。
答案 4 :(得分:0)
随着API Gateway区域端点于2017年11月启动,我认为现在最好将它们与CloudFront Distributions一起使用。有关从Edge Optimized API迁移到Regional API以及设置CloudFront分布的一些详细说明,请参见: