5

У меня есть экземпляр AWS Lambda, который подключается к определенному AWS API Gateway. Если я включу CORS и даю access-control-allow-origin определение http://example.com, то я могу получить доступ к экземпляру Lambda от http://example.com. Однако, если я использую https://example.com, он не работает.AWS API Gateway - CORS «access-control-allow-origin» - несколько записей

Значит, в AWS, как я могу определить использование нескольких значений access-control-allow-origin без использования подстановочного знака? Я пробовал использовать что-то вроде *.example.com, но это не работает.

EDIT: Если я использую '*' в качестве моего значения на шлюзе API, но устанавливаю правила CORS на своем ведро S3, это было бы безопасно? Пример для правил ковша:

<?xml version="1.0" encoding="UTF-8"?> 
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 
    <CORSRule> 
     <AllowedOrigin>http://example.com</AllowedOrigin> 
     <AllowedMethod>GET</AllowedMethod> 
     <AllowedMethod>POST</AllowedMethod> 
     <AllowedMethod>PUT</AllowedMethod> 
     <MaxAgeSeconds>3000</MaxAgeSeconds> 
     <AllowedHeader>*</AllowedHeader> 
    </CORSRule> 
    <CORSRule> 
     <AllowedOrigin>https://example.com</AllowedOrigin> 
     <AllowedMethod>GET</AllowedMethod> 
     <AllowedMethod>POST</AllowedMethod> 
     <AllowedMethod>PUT</AllowedMethod> 
     <MaxAgeSeconds>3000</MaxAgeSeconds> 
     <AllowedHeader>*</AllowedHeader> 
    </CORSRule> 
    <CORSRule> 
     <AllowedOrigin>https://www.example.com</AllowedOrigin> 
     <AllowedMethod>GET</AllowedMethod> 
     <AllowedMethod>POST</AllowedMethod> 
     <AllowedMethod>PUT</AllowedMethod> 
     <MaxAgeSeconds>3000</MaxAgeSeconds> 
     <AllowedHeader>*</AllowedHeader> 
    </CORSRule> 
</CORSConfiguration> 
+0

Такая же проблема здесь. Моя ситуация заключается в том, что я должен использовать параметр withCredentials(), поэтому нельзя разрешить шаблон. Мне, возможно, придется обращаться с заголовками кормов, а не позволять apigw обрабатывать его. Странно, что они предоставляют правила CORS для s3, но не для apigatway. – Taichi

ответ

5

К сожалению, это невозможно сегодня. Спецификация CORS не допускает частичные дикие карты, и в настоящее время API Gateway допускает только одно статическое значение для заголовка.

Возможно, вы сможете перегрузить метод OPTIONS для динамического возвращения этого значения на основе заголовка входящего узла.

+0

Спасибо, Боб. Я знаю, что не рекомендуется использовать '*' для значения (которое работает, так как все идет), но для низкопрофильного сайта вы считаете, что это вызовет какую-либо проблему? – Wes

+0

@Wes, который зависит от уровня риска, который вы готовы принять. Если это всего лишь вопрос http vs https, вы, вероятно, можете решить эту проблему, перенаправляя клиентов на https всегда. С помощью [Firefox] (https://blog.mozilla.org/security/2015/04/30/deprecating-non-secure-http/) и [Chrome] (https://blog.chromium.org/2016/09/двигающийся в направлении, дополнительной небезопасной-сети.html), перемещаясь к устаревшему http, это имеет смысл и не должно быть слишком сложным. –

8

Это всегда было досадой с CORS, если вы хотите включить несколько Origins.

Общий обходной путь в других системах (например, экспресс/Nginx и т.д.) заключается в следующем:

  • осматривают Origin заголовок, отправленный браузером
  • проверить его против белого списка происхождения
  • , если он соответствует , вернуть входящий Origin как заголовок Access-Control-Allow-Origin, иначе возвращает заполнитель (по умолчанию начало координат)

Это не возможно, используя автосервисную поддержку CORS от AWS-Gateway, используя макетную интеграцию, однако возможно, если вы напишете свой собственный код для обработки запроса OPTIONS.

Ниже приведен пример кода, написанного с лямбда-прокси интеграций:

const allowedOrigins = [ 
    "http://example.com", 
    "http://example.com:8080", 
    "https://example.com", 
    "https?://[a-z]*.?myapp.com", 
    "http://localhost:[0-9]*" 
]; 

exports.handler = (event, context) => { 
    const origin = event.headers.Origin || event.headers.origin; 
    var goodOrigin = false; 

    if (origin) { 
     allowedOrigins.forEach(allowedOrigin => { 
      if (!goodOrigin && origin.match(allowedOrigin)) { 
       goodOrigin = true; 
      } 
     }); 
    } 

    context.succeed({ 
     headers: { 
      "Access-Control-Allow-Headers": "Accept,Accept-Language,Content-Language,Content-Type,Authorization,x-correlation-id", 
      "Access-Control-Expose-Headers": "x-my-header-out", 
      "Access-Control-Allow-Methods": "DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT", 
      "Access-Control-Allow-Origin": goodOrigin ? origin : allowedOrigins[0] 
     }, 
     statusCode: 204 
    }); 
}; 

Сохранить как лямбда-функции. Чтобы установить это в API-Gateway, добавьте метод OPTIONS, а для Integration Request выберите Lambda Function с Use Lambda Proxy integration.

Конечно, недостатком этого является то, что вы платите за лямбда-функции, а вызов функции лямбда, вероятно, будет дополнительным 50 мс латентностью по сравнению с макетной интеграцией.