如何在API网关前添加CloudFront

ryn*_*nop 33 cdn amazon-web-services amazon-cloudfront aws-api-gateway

API网关(APIG),虽然它使用CloudFront(CF),但它不支持CDN边缘缓存.当我配置CF分发以使用API​​G作为自定义源时,我收到权限被拒绝错误.

如何配置CF来解决这个问题?

ryn*_*nop 53

在API网关(APIG)通过其内部使用CloudFormation(CF)支持边缘缓存之前,我已经提出了一种解决方法.

你确实可以把CF dist放在APIG前面,诀窍是强制HTTPS只有"查看器协议策略"AND不转发HOST头,因为APIG需要SNI.

我设置我的CF"默认缓存行为设置"不转发任何标头,并强制"查看器协议策略"为"仅HTTPS",它的工作原理.希望这有助于其他人.

这是一个具有所有必需配置<stage>--<app name>的CloudFormation 资源对象(注意:我使用StackName 的约定):

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
Run Code Online (Sandbox Code Playgroud)

2018年末更新

  • CloudFormation最终支持设置SSL proto ver: MinimumProtocolVersion: TLSv1.1_2016
  • 我已经将这个(以及许多其他)最佳实践融入到OSS项目中:aws-blueprint

  • API Gateway在后台使用CloudFront.如果您将另一个CloudFront分配指向API Gateway端点,CloudFront会阻止该请求,因为CloudFront具有反环回检查.即您无法在CloudFront上指向CloudFront.AWS re-Invent 2015的AWS工程师告诉我,将放宽此反环回检查,以便您将CloudFront分配指向API网关.我还没有确认它是否有效. (11认同)
  • 我甚至无法描述知道多少时间转发主机标头可以节省人们的时间. (9认同)
  • 首先,是的,删除主机头是完成这项工作所需要的.我很好奇是否有人尝试将ApiGateway设置为IAM身份验证.我收到了签名错误.它期望host = apigateway主机的签名而不是host = cloudfront主机 (2认同)

Sol*_*olo 9

添加到以前的答案:

重要的是行为路径模式实际上是匹配“真实”路径的东西。


如果 API 端点是 <id>.execute-api.<region>.amazonaws.com/stage-name/my-api

而源域+路径是 <id>.execute-api.<region>.amazonaws.com/stage-name

行为路径模式必须是 my-apimy-api/*my-api/something,等


我不知道为什么,但我认为路径模式可以用作别名,例如:

https://www.example.com/random-name(路径模式random-name)解析为域 + 原点设置的路径,例如<id>.execute-api.<region>.amazonaws.com/stage-name.

事实并非如此。

  • 以下是 AWS CDK 中的实现:https://github.com/cadbox1/backend-frontend-aws-cdk/blob/master/lib/lambda-cdk-stack.ts (3认同)