2016-09-22 56 views
5

Mam instancję AWS Lambda, która łączy się z określoną bramą interfejsu API AWS. Jeśli włączę CORS i podam access-control-allow-origin definicję http://example.com, wówczas będę mógł uzyskać dostęp do instancji Lambda z http://example.com. Jeśli jednak używam https://example.com, to nie działa.AWS API Gateway - CORS "access-control-allow-origin" - wiele wpisów

W AWS, jak zdefiniować za pomocą wielu wartości access-control-allow-origin bez użycia symbolu wieloznacznego? Próbowałem użyć czegoś takiego jak *.example.com, ale to nie działa.

EDYCJA: Jeśli użyję '*' jako mojej wartości na bramie API, ale ustawię zasady CORS na moim wiadrze S3, czy to będzie bezpieczne? Przykład reguł dla kubełków:

<?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

Ten sam numer tutaj. Moja sytuacja jest taka, że ​​muszę użyć opcji withCredentials(), więc żadna z symboli wieloznacznych nie jest dozwolona. Być może będę musiał sam sobie poradzić z nagłówkami cors, zamiast pozwolić, by apigw sobie z tym poradził. To jest tak dziwne, że zapewniają zasady CORS dla s3, ale nie dla apigacji. – Taichi

Odpowiedz

5

Niestety nie jest to możliwe dzisiaj. Specyfikacja CORS nie zezwala na częściowe karty wieloznaczne, a obecnie bramka API zezwala tylko na jedną statyczną wartość nagłówka.

Może być możliwe przeciążenie metody OPTIONS w celu dynamicznego zwrócenia tej wartości na podstawie nagłówka przychodzącego hosta.

+0

Dzięki Bob. Wiem, że nie zaleca się używania '*' dla wartości (która działa, ponieważ cokolwiek się dzieje), ale dla witryny o niskim profilu uważasz, że spowodowałoby to jakiś problem? – Wes

+0

@W zależności od poziomu ryzyka, który akceptujesz. Jeśli jest to tylko kwestia http i https, prawdopodobnie możesz rozwiązać ten problem, przekierowując klientów do https zawsze. Z [Firefox] (https://blog.mozilla.org/security/2015/04/30/deprecating-non-secure-http/) i [Chrome] (https://blog.chromium.org/2016/09/przejście w stronę bardziej bezpiecznej sieci.html) w kierunku wycofywania http, to ma sens i nie powinno być zbyt trudne. –

8

To zawsze było irytujące dla CORS, jeśli chcesz włączyć kilka początków.

Wspólna obejście w innych systemach (np wyrazić/nginx etc) jest:

  • sprawdzić nagłówek Origin wysłana przez przeglądarkę
  • sprawdzić go na białej liście początków
  • czy pasuje , zwróć przychodzące Origin jako nagłówek Access-Control-Allow-Origin, a następnie zwróć obiekt zastępczy (domyślne pochodzenie)

To nie jest Możliwe, że dzięki automatycznej obsłudze CORS AWS-Gateway używa się fałszywej integracji, jest jednak możliwe, jeśli napiszesz własny kod, aby przetworzyć żądanie OPTIONS.

Poniżej przykładowy kod napisany z integracji lambda proxy:

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 
    }); 
}; 

ten Zapisz jako funkcji lambda. Aby skonfigurować tę funkcję w bramce interfejsu API, dodaj metodę OPTIONS i zaznacz opcję z wyborem Lambda Function z .

Oczywiście wadą tego jest to, że płacisz za funkcje lambda, a wywołanie funkcji lambda prawdopodobnie będzie dodatkowym opóźnieniem 50ms w stosunku do fałszywej integracji.