Включить CORS при локальном запуске AWS SAM CLI

Всякий раз, когда я пытаюсь получить доступ к серверной лямбда-функции через POST через браузер, я получаю сообщение об ошибке

Ответ на запрос предварительной проверки не проходит проверку контроля доступа: в запрашиваемом ресурсе присутствует заголовок No > Access-Control-Allow-Origin.

Когда это /GET это работает хорошо, я прочитал это, потому что это не отправляет предварительный запрос полета. Когда я изменяю это на POST это когда это не удается.

Команда, которую я запускаю:

sam local start-api

И мой template.yaml это:

...

Resources:
    PropertiesFunction:
        Type: AWS::Serverless::Function
        Properties:
            CodeUri: target/service-0.0.1-SNAPSHOT.jar
            Handler: com.aws.PropertiesHandler::handleRequest
            Runtime: java8
            Events:
                PropertiesApi:
                    Type: Api
                    Properties:
                        Path: /properties
                        Method: post

...

Как я могу включить CORS на этих конечных точках?

4 ответа

У меня была такая же ошибка, и я уже исправил ее за 3 шага. (AWS Lambda в Java8, SAM CLI v0.37.0)

  1. Добавьте параметры для заголовка:
    Map<String, String> headers = new HashMap<>();
    headers.put("Content-Type", "application/json");
    headers.put("X-Custom-Header", "application/json");
    headers.put("Access-Control-Allow-Origin", "*");
    headers.put("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, PATCH, DELETE");
    headers.put("Access-Control-Allow-Headers", "X-Requested-With,content-type");
  1. Добавить вариант Cors в template.yaml
    Globals:
      Function:
        Timeout: 20
      Api:
        Cors:
          AllowMethods: "'GET,POST,OPTIONS'"
          AllowHeaders: "'content-type'"
          AllowOrigin: "'*'"
          AllowCredentials: "'*'"
  1. Обновить функцию ресурса свойств в template.yaml
          Events:
            HelloWorld:
              Type: Api 
              Properties:
                # Path: /hello
                # Method: get
                Path: "/{proxy+}"
                Method: ANY

Во-первых, вам нужно добавить следующий раздел в template.yml, чтобы включить cors в шлюзе API:

Globals:
  Api:
    Cors:
      AllowMethods: "'GET,POST,OPTIONS'"
      AllowHeaders: "'content-type'"
      AllowOrigin: "'*'"
      AllowCredentials: "'*'"

Затем в вашем ответе лямбда-функции


        MultivaluedMap<String, Object> headers = responseContext.getHeaders();

        headers.add("Access-Control-Allow-Origin", "*");
        headers.add("Access-Control-Allow-Headers", requestContext.getHeaderString("Access-Control-Request-Headers"));
        headers.add("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,HEAD,OPTIONS");

Вы должны иметь возможность обойти это для локального тестирования, явно добавив следующие заголовки к вашему ответу в своей функции обработчика:

    "Access-Control-Allow-Origin": "*"

Вы можете использовать переменную окружения, которая добавляет заголовки, только если вы работаете локально.

Вот простой пример Python из функции обработчика, которую я имею:

   if not all(field in values for field in required_fields):
    response = {
        'statusCode': 400,
        'body': json.dumps(
            {
                'message': 'Required data missing from request body'
            }
        )        
    }
    # explicitly add CORs headers for local testing
    response['headers'] = {"Access-Control-Allow-Origin": "*"}
    return response

Это подходит только для локального тестирования, когда развертывание в API-интерфейсе шлюза API выполняется посредством конфигурации на API-шлюзе.

Это решение работало для меня, пока я не добавил авторизацию в API с пулом пользователей Cognito, через который я сейчас пытаюсь работать.

Вот аналогичный пост по проблеме: Как включить CORS для ресурса шлюза API AWS

Вот ссылка на это в официальной документации AWS.

Попробуйте это в своем бессерверном файле шаблона, если вы используете SAM

      "Globals": {
    "Api": {
      "Cors": {
        "AllowMethods": "'POST, GET, PUT, DELETE'",
        "AllowHeaders": "'content-type'",
        "AllowOrigin": "'*'"
      }
    }
}