AWS API Gateway поддерживает CORS for OPTIONS только при использовании SAM (без интеграции с прокси-сервером Lambda)

Я использую AWS Serverless для создания небольшого сайта с примерно 15 функциями Lambda.
Мой стек Cloudformation полностью построен с использованием SAM.

Я НЕ использую интеграцию с лямбда-прокси.

Раздел Api в конфигурации шаблона SAM yaml выглядит так:

AppApi:
    Type: AWS::Serverless::Api
    Properties:
        Cors:
            AllowMethods: "'*'"
            AllowHeaders: "'Content-Type'" 
            AllowOrigin: "'*'"
    ...........More Stuff..........

Когда я развертываю этот шаблон SAM yaml, я вижу, что мой ApiGateway создал команду OPTIONS для всех методов, и когда я отправляю запрос с помощью команды OPTIONS, я правильно вижу заголовки CORS.

Проблема в том, что другие глаголы (например, POST) не добавляют эти заголовки в свой ответ, как это сделал запрос OPTIONS, и когда я запускаю свой api из браузера, я получаю ошибку политики перекрестного происхождения в моей консоли.

Итак, моим текущим обходным путем было добавление заголовка CORS с использованием интегрированных ответов на определенные коды состояния, но я не могу и не хочу обрабатывать это для 15 методов, и я хочу поддерживать все коды состояния ответа (например, 4xx \ 5xx и т. Д.).

Мои вопросы:

  1. Я здесь что-то не так делаю или это SAM ошибка?
  2. Если это ошибка, есть ли какое-либо обходное решение, кроме добавления заголовков с использованием интегрированных ответов (или из моего кода)?
  3. Есть ли способ добавить заголовки «глобально» из шлюза Api? Или поддерживать какие-то глобальные комплексные ответы?

person Amir Popovich    schedule 12.03.2019    source источник


Ответы (1)


Если вы используете Lambda с интеграцией прокси, вам необходимо указать CORS Origin в своем HTTP-ответе.

Для интеграции Lambda или HTTP-прокси вы по-прежнему можете настроить требуемые заголовки ответов OPTIONS в API Gateway. Однако вы должны полагаться на то, что серверная часть вернет заголовки Access-Control-Allow-Origin, потому что ответ интеграции отключен для интеграции прокси. https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html

Все ответы от Lambda должны иметь эти заголовки и код состояния, но вы можете извлечь их в общую библиотеку, чтобы уменьшить дублирование кода. Заголовки ошибок, обрабатываемых API-G, добавляются автоматически.

Вероятно, он у вас уже есть, но шаблон NodeJS выглядит так:

var response = {
    statusCode: 200,
    headers: {
        "Access-Control-Allow-Origin" : "*"
    },
    body: JSON.stringify({
        someReturnData
    })
};
callback(null, response);

Если вы действительно не хотите этого делать, вы можете отключить интеграцию Lambda-Proxy, но это означает, что все полезные данные ответа на запросы должны обрабатываться в API-G, а не в Lambda. ИМО это обеспечивает гораздо меньшую гибкость и большую конфигурацию, необходимую для достижения тех же результатов.

Вот интересное сравнение двух подходов.

person Matt D    schedule 12.03.2019
comment
Привет, спасибо за ответ. Я НЕ использую Lambda с прокси int. и я не хочу добавлять заголовки CORS в свой код, так как считаю это плохой практикой по многим причинам (одна из них заключается в том, что вы можете получить ответ от ресурса перед вводом кода, а затем как вы будете поддерживать CORS?) . Теперь мои альтернативы - это интегрированные ответы для каждого метода \ глагола - тоже плохо, так как я не хочу покрывать все коды ошибок (кто знает, какой код ошибки я пропущу), и я не хочу спамить свой шаблон YAML и обрабатывать каждое изменение для каждого метода \ глагола. Я ищу лучший способ сделать это .. - person Amir Popovich; 12.03.2019
comment
Если вы не используете Lambda-Proxy и настроили заголовки CORS в API Gateway, вы должны автоматически получить заголовки в ответе. В качестве теста пробовали ли вы вручную включить CORS одним методом (консоль или интерфейс командной строки), чтобы посмотреть, работает ли это. - person Matt D; 12.03.2019
comment
да. Я добавил в свой шаблон раздел CORS. После развертывания шаблона для каждого пути к ресурсу использовалась команда OPTIONS, которая возвращает действительный ответ. Когда браузер создает запрос xhr, он выполняет предварительную проверку с помощью запроса OPTIONS, который возвращает все правильно, а затем переходит к реальному запросу (допустим, POST). Запрос POST не возвращает заголовки CORS, а затем браузер просто отклоняет ответ. Я не знаю, ошибка это или что-то, чего мне здесь не хватает ... - person Amir Popovich; 12.03.2019
comment
Извините, я не понимаю, что там происходит. Я перешел на Lambda-Proxy несколько лет назад, и CORS стал гораздо менее серьезной проблемой. Lambda-Proxy настоятельно рекомендуется на обсуждениях AWS Talks, на которых я был, и на бессерверных встречах, которые я посещаю. Я должен признать, что я мало использую SAM, в основном бессерверный фреймворк. - person Matt D; 12.03.2019