Setting Up CORS and Integration on AWS API Gateway Using CloudFormation

Cross-Origin Resource Sharing (CORS) is an essential security mechanism utilized by web browsers, allowing for regulated access to server resources from origins that differ in domain, protocol, or port. In the realm of APIs, especially when utilizing AWS API Gateway, configuring CORS is crucial to facilitate access for web applications originating from various domains while mitigating potential security risks.

This article aims to provide a comprehensive guide on CORS and integrating AWS API Gateway through CloudFormation. It will emphasize the significance of CORS, the development of authorization including bearer tokens, and the advantages of selecting optional methods in place of standard GET requests.

Why CORS Matters

In the development of APIs intended for access across various domains, CORS is essential in mitigating unauthorized access. By delineating the specific domains permitted to interact with your API, you can protect your resources from Cross-Site Request Forgery (CSRF) attacks while allowing valid cross-origin requests.

Benefits of CORS

  1. Security: CORS plays a crucial role in regulating which external domains can access your resources, thereby safeguarding your API against harmful cross-origin requests.  
  2. Flexibility: CORS allows you to define varying levels of access (such as methods like GET, POST, DELETE, etc.) for different origins, offering adaptability based on your specific requirements.  
  3. User experience: Implementing CORS enhances user experience by allowing users to seamlessly access resources from multiple domains without encountering access-related problems.  

Before we proceed with setting up CORS, we need to understand the need to use optional methods over GET. This comparison helps in quickly comparing the aspects of using GET versus optional methods (PUT, POST, OPTIONS) in API requests.

Reason GET Optional Methods (POST, PUT, OPTIONS)
Security GET requests are visible in the browser's address bar and can be cached, making it less secure for sensitive information. Optional methods like POST and PUT are not visible in the address bar and are not cached, providing more security for sensitive data.
Flexibility GET requests are limited to sending data via the URL, which restricts the complexity and size of data that can be sent. Optional methods allow sending complex data structures in the request body, providing more flexibility.
Idempotency and Safety GET is idempotent and considered safe, meaning it does not modify the state of the resource. POST and PUT are used for actions that modify data, and OPTIONS are used for checking available methods.
CORS Preflight GET requests are not typically used for CORS preflight checks. OPTIONS requests are crucial for CORS preflight checks, ensuring that the actual request can be made.


Comparison between POST and PUT methods, the purposes and behavior:

Aspect POST PUT
Purpose Used to create a new resource. Used to update an existing resource or create it if it doesn't exist.
Idempotency Not idempotent; multiple identical requests may create multiple resources. Idempotent; multiple identical requests will not change the outcome beyond the initial change.
Resource Location The server decides the resource's URI, typically returning it in the response. The client specifies the resource's URI.
Data Handling Typically used when the client does not know the URI of the resource in advance. Typically used when the client knows the URI of the resource and wants to update it.
Common Use Case Creating new records, such as submitting a form to create a new user. Updating existing records, such as editing user information.
Caching Responses to POST requests are generally not cached. Responses to PUT requests can be cached as the request should result in the same outcome.
Response Usually returns a status code of 201 (Created) with a location header pointing to the newly created resource. Usually returns a status code of 200 (OK) or 204 (No Content) if the update is successful.


Setting Up CORS in AWS API Gateway Using CloudFormation

Configuring CORS in AWS API Gateway can be accomplished manually via the AWS Management Console; however, automating this process with CloudFormation enhances both scalability and consistency. 

Below is a detailed step-by-step guide:

1. Define the API Gateway in CloudFormation

Start by defining the API Gateway in your CloudFormation template:

YAML
 
Resources:

  MyApi:

    Type: AWS::ApiGateway::RestApi

    Properties:

      Name: MyApi


2. Create Resources and Methods

Define the resources and methods for your API. For example, create a resource for /items and a GET method:

YAML
 
  ItemsResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      ParentId: !GetAtt MyApi.RootResourceId
      PathPart: items
      RestApiId: !Ref MyApi

  GetItemsMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: GET
      ResourceId: !Ref ItemsResource
      RestApiId: !Ref MyApi
      Integration:
        Type: MOCK
        IntegrationResponses:
          - StatusCode: 200
      MethodResponses:
        - StatusCode: 200


3. Configure CORS

Next, configure CORS for your API method by specifying the necessary headers:

YAML
 
  OptionsMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: OPTIONS
      ResourceId: !Ref ItemsResource
      RestApiId: !Ref MyApi
      Integration:
        Type: MOCK
        RequestTemplates:
          application/json: '{"statusCode": 200}'
        IntegrationResponses:
          - StatusCode: 200
          	SelectionPattern: '2..'
            ResponseParameters:
              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-Methods: "'*'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
      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


Incorporating Authorization

Implementing authorization within your API methods guarantees that access to specific resources is restricted to authenticated and authorized users. The AWS API Gateway offers various authorization options, including AWS Lambda authorizers, Cognito User Pools, and IAM roles.

YAML
 
  MyAuthorizer:
    Type: AWS::ApiGateway::Authorizer
    Properties:
      Name: MyLambdaAuthorizer
      RestApiId: !Ref MyApi
      Type: TOKEN
      AuthorizerUri: arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/<lambda_arn>/invocations

  GetItemsMethodWithAuth:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: CUSTOM
      AuthorizerId: !Ref MyAuthorizer
      HttpMethod: GET
      ResourceId: !Ref ItemsResource
      RestApiId: !Ref MyApi
      Integration:
        Type: AWS_PROXY
        IntegrationHttpMethod: POST
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations
      MethodResponses:
        - StatusCode: 200


After implementation, here's how the API looks in AWS:

How the API looks in AWS


Integration request:
Integration request

API Gateway Documentation can be found here: Amazon API.

Conclusion

Establishing CORS and integrating AWS API Gateway through CloudFormation offers an efficient and reproducible method for managing API access. By meticulously setting up CORS, you guarantee that your APIs remain secure and are accessible solely to permitted origins. Incorporating authorization adds a layer of security by limiting access to only those users who are authorized. Moreover, evaluating the advantages of utilizing optional methods instead of GET requests ensures that your API maintains both security and the flexibility necessary for managing intricate operations.

The implementation of these configurations not only bolsters the security and performance of your API but also enhances the overall experience for end-users, facilitating seamless cross-origin interactions and the appropriate management of sensitive information.

 

 

 

 

Top