DEV Community

loading...

cors with apigw

chiefbiiko profile image chiefbiiko ・2 min read

cors with apigw

🌐🔗🌒🐙

lets assume a freshly mounted apigw with a resource /pitbulls having two endpoints serving and accepting json:

GET /pitbulls

POST /pitbulls

once you start hitting these from a browser they need to have cors enabled..

determining cors request types

there are two types of cors requests: simple and non-simple - refer to these AWS docs MDN docs 4 specifics.

a simple requests has the following characteristics:

  • GET, HEAD, or POST

  • if POST the request must include an origin header

  • request payload content type is text/plain, multipart/form-data, or application/x-www-form-urlencoded

  • no custom headers

steps 2 enable cors

4 simple requests

scenario: GET /pitbulls

the backend response must include an Access-Control-Allow-Origin header granting access to the request's origin domain. Note that one should specify protocol, domain, and port when defining the origin.

backend response to a simple cors request

return {
  statusCode: 200,
  headers: {
    "access-control-allow-origin": "https://your.domain:443",
    "content-type": "application/json"
  },
  body: '[{"name":"dogo"}]'
}
Enter fullscreen mode Exit fullscreen mode

4 non-simple requests

scenario: POST /pitbulls with request payload content-type: application/json

our pitbulls resource needs to expose an OPTIONS method that responds to cors preflight requests with the following cors headers: Access-Control-Allow-Methods Access-Control-Allow-Headers Access-Control-Allow-Origin

cors options method snippet in cloudformation

CorsMethod:
  Type: AWS::ApiGateway::Method
  Properties:
    AuthorizationType: NONE
    RestApiId: !Ref RestApi
    ResourceId: !Ref PitbullsResource
    HttpMethod: OPTIONS
    Integration:
      Type: MOCK
      IntegrationResponses:
        - StatusCode: 200
          ResponseParameters:
            method.response.header.Access-Control-Allow-Headers: "'content-type'"
            method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET,POST'"
            method.response.header.Access-Control-Allow-Origin: !If
              - IsProd
              - "'https://your.domain:443'"
              - "'*'"
          ResponseTemplates:
            application/json: ''
      PassthroughBehavior: WHEN_NO_MATCH
      RequestTemplates:
        'application/json': '{"statusCode":200}'
    MethodResponses:
      - StatusCode: 200
        ResponseModels:
          application/json: Empty
        ResponseParameters:
          method.response.header.Access-Control-Allow-Headers: False
          method.response.header.Access-Control-Allow-Methods: False
          method.response.header.Access-Control-Allow-Origin: False

Enter fullscreen mode Exit fullscreen mode

Additionally, the backend, lambdas, ec2s or whatever, need to also respond with the three cors headers listed above.

backend responding to a non-simple cors request with mandated headers

return {
  statusCode: 201,
  headers: {
    "access-control-allow-headers": "content-type",
    "access-control-allow-methods": "OPTIONS,POST",
    "access-control-allow-origin": "https://your.domain:443",
  },
}
Enter fullscreen mode Exit fullscreen mode

🐙🌐🔗🌒 ~ AWS API Gateway CORS

Discussion (0)

pic
Editor guide