API Gateway CORS: brak nagłówka „Access-Control-Allow-Origin”

106

Chociaż CORS został skonfigurowany za pośrednictwem API Gateway i ustawiono Access-Control-Allow-Originnagłówek, nadal otrzymuję następujący błąd podczas próby wywołania interfejsu API z AJAX w przeglądarce Chrome:

XMLHttpRequest nie może załadować http://XXXXX.execute-api.us-west-2.amazonaws.com/beta/YYYYY . Żądany zasób nie zawiera nagłówka „Access-Control-Allow-Origin”. W związku z tym źródło „null” nie ma dostępu. Odpowiedź miała kod stanu HTTP 403.

Próbowałem uzyskać adres URL przez Postman i pokazuje, że powyższy nagłówek został pomyślnie przekazany:

Przekazane nagłówki

A z odpowiedzi OPCJE:

Nagłówki odpowiedzi

Jak mogę wywołać mój interfejs API z przeglądarki bez powrotu do JSON-P?

Tyler
źródło
Czy masz to skonfigurowane na S3? Jeśli tak, czy mógłbyś ustawić Bucket Policy? Upewnij się, że masz metodę w swojej polityce
iSkore
12
Zespół API Gateway tutaj ... Jeśli używasz funkcji „Włącz CORS” w konsoli, konfiguracja powinna być poprawna. Moim najlepszym przypuszczeniem byłoby to, że nie wywołujesz poprawnej ścieżki zasobów w swoim API w JavaScript, który wykonuje przeglądarka. Jeśli spróbujesz wykonać wywołanie interfejsu API do nieistniejącej metody / zasobu / etapu, otrzymasz ogólny 403 bez nagłówków CORS. Nie widzę, jak przeglądarka może przegapić nagłówek Access-Control-Allow-Origin, jeśli dzwonisz do właściwego zasobu, ponieważ wywołanie OPTIONS w programie Postman wyraźnie zawiera wszystkie właściwe nagłówki CORS.
jackko
1
@ RyanG-AWS klient nie podpisuje żądania, ponieważ API jest uwierzytelniane przez zasób, który wywołuje, przy użyciu tokena specyficznego dla użytkownika, więc poświadczenia nie są czynnikiem. Mogę wywołać API, odwiedzając URL bezpośrednio w przeglądarce i otrzymuję odpowiednią odpowiedź.
Tyler,
2
@makinbacon: Czy znalazłeś na to rozwiązanie? Przechodzę tutaj przez ten sam problem.
Nirmal
1
Moje metody i etap zostały wygenerowane automatycznie przez Lambdę. Po fakcie włączyłem CORS. Te same błędy co w przypadku OP. Zdmuchnąłem automatycznie generowane rzeczy, stworzyłem nowe API i metody, wdrożyłem na nowym etapie i działało dobrze.
oparzenie

Odpowiedzi:

125

Mam ten sam problem. Wykorzystałem 10 godzin, aby się dowiedzieć.

https://serverless.com/framework/docs/providers/aws/events/apigateway/

// handler.js

'use strict';

module.exports.hello = function(event, context, callback) {

const response = {
  statusCode: 200,
  headers: {
    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS 
  },
  body: JSON.stringify({ "message": "Hello World!" })
};

callback(null, response);
};
Riseres
źródło
Naprawiono również problem, który miałem. Dziękuję za Twoją odpowiedź!
Eric Brown,
Nie używam serverless, ale to rozwiązało mój problem. Chyba musisz przekazać te nagłówki z rzeczywistego źródła.
Costa
2
FYI, jest problem z przedstawionym tutaj przykładem. Jeśli masz „Access-Control-Allow-Credentials”: ​​true, nie możesz mieć symbolu wieloznacznego * dla Access-Control-Allow-Origin. Ta reguła jest wymuszana przez przeglądarkę. Zobacz tutaj i tutaj
Kevin
1
To nie działa, ponownie pokazuje ten sam błąd pola nagłówka żądania Access-Control-allow-credentials nie jest dozwolone przez Access-Control-Allow-Headers w odpowiedzi przed inspekcją.
mitesh7172
1
Dla każdego, kto jest ciekawy, oto oficjalna dokumentacja wspominająca o tym: docs.aws.amazon.com/apigateway/latest/developerguide/… > W przypadku integracji Lambda lub HTTP proxy nadal można ustawić wymagane nagłówki odpowiedzi> OPTIONS w API Gateway. Musisz jednak polegać na zapleczu>, aby zwrócić nagłówki Access-Control-Allow-Origin, ponieważ odpowiedź integracji> jest wyłączona dla integracji proxy.
Leonid Usov
109

Jeśli ktoś jeszcze korzysta z tego nadal - udało mi się wyśledzić główną przyczynę w mojej aplikacji.

Jeśli korzystasz z API-Gateway z niestandardowymi autoryzatorami - API-Gateway odeśle 401 lub 403 z powrotem, zanim faktycznie trafi na twój serwer. Domyślnie - API-Gateway NIE jest skonfigurowane dla CORS podczas zwracania 4xx od niestandardowego autoryzatora.

Ponadto - jeśli zdarza się, że otrzymujesz kod stanu z 0lub 1z żądania przechodzącego przez API Gateway, prawdopodobnie jest to twój problem.

Aby to naprawić - w konfiguracji API Gateway przejdź do „Gateway Responses”, rozwiń „Default 4XX” i dodaj tam nagłówek konfiguracji CORS. to znaczy

Access-Control-Allow-Origin: '*'

Pamiętaj, aby ponownie wdrożyć swoją bramę - i voila!

Gabriel Doty
źródło
7
kocham Cię. poważnie nad tym pracowałem przez dwa dni.
efong5
4
Dla tych, którzy chcą to zrobić z AWS CLI, użyj:aws apigateway update-gateway-response --rest-api-id "XXXXXXXXX" --response-type "DEFAULT_4XX" --patch-operations op="add",path="/responseParameters/gatewayresponse.header.Access-Control-Allow-Origin",value='"'"'*'"'"'
Will
1
Nie używam niestandardowych autoryzatorów i nadal potrzebuję tego, ponieważ moja prośba zawierała zły kod JSON - dziękuję!
Force Hero
9
uwaga dla siebie - nie zapomnij później wdrożyć API :)
danieln
2
Dziwne, to zadziałało dla mnie, ale nie musiałem ponownie wdrażać. Próbowałem ponownie wdrożyć wcześniej. Nie wiem, dlaczego to zadziałało.
Michael
19

1) Musiałem zrobić to samo co @riseres i kilka innych zmian, oto moje nagłówki odpowiedzi:

headers: {
            'Access-Control-Allow-Origin' : '*',
            'Access-Control-Allow-Headers':'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
            'Access-Control-Allow-Credentials' : true,
            'Content-Type': 'application/json'
        }

2) I

Zgodnie z tą dokumentacją:

http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html

Gdy używasz serwera proxy dla funkcji lambda w konfiguracji bramy API, metody post lub get nie mają dodanych nagłówków, tylko opcje. Musisz to zrobić ręcznie w odpowiedzi (odpowiedź serwera lub lambda).

3) I

Poza tym musiałem wyłączyć opcję `` Wymagany klucz API '' w mojej metodzie wysyłania bramy API.

Carlos Alberto Schneider
źródło
5
Tak, myślę, że subtelną rzeczą, której wielu z nas początkowo tęskni, jest to, że po skonfigurowaniu integracji API Gateway dla funkcji Lambda z „Użyj integracji Lambda Proxy”, musisz zrobić to, co deklarujesz ty i inni, i upewnić się, że nagłówki są dodane programowo w odpowiedzi lambda. Elementy auto-gen, które są tworzone przez „Włączanie CORS” w bramie API i tworzą odpowiedź OPTIONS, są świetne, ale nie prowadzą do tego celu, jeśli ustawisz opcję „Użyj integracji Lambda Proxy” w żądaniu integracji w API Przejście.
1
U mnie to zadziałało ... po poprawnym przeczytaniu instrukcji: Ważne Podczas stosowania powyższych instrukcji do metody ANY w integracji proxy żadne odpowiednie nagłówki CORS nie zostaną ustawione. Zamiast tego zaplecze musi zwrócić odpowiednie nagłówki CORS, takie jak Access-Control-Allow-Origin. docs.aws.amazon.com/apigateway/latest/developerguide/…
BennyHilarious
19

Jeśli wypróbowałeś wszystko w tym problemie bezskutecznie, skończysz tam, gdzie ja. Okazuje się, że istniejące wskazówki dotyczące konfiguracji CORS firmy Amazon działają dobrze ... po prostu pamiętaj o ponownym wdrożeniu ! Kreator edycji CORS, nawet ze wszystkimi ładnymi małymi zielonymi znacznikami, nie aktualizuje na żywo twojego API. Być może oczywiste, ale zszokowało mnie to na pół dnia.

wprowadź opis obrazu tutaj

lase
źródło
2
To było to. Pracuję nad tym dosłownie przez dwa dni. Nie jestem pewien, czy logika nie będzie przynajmniej monitować o ponowne wdrożenie po edycji bramy.
Chris Christensen
@ChrisChristensen cieszę się, że to zrozumiałeś - zawsze jest coś tak łagodzącego, ale niesamowicie pokonującego w takich problemach
lase
To jest odpowiedź, która obowiązuje w 2020 roku. Dzięki
Rahul Khanna
1
RE-DEPLOY RE-DPLOY RE-DEPLOY
Surjith SM
12

Moja próbka działa: właśnie wstawiłem „Access-Control-Allow-Origin”: „*”, wewnątrz nagłówków: {} w wygenerowanej funkcji Lambda nodejs. Nie wprowadziłem żadnych zmian w warstwie API generowanej przez Lambda.

Oto mój NodeJS:

'use strict';
const doc = require('dynamodb-doc');
const dynamo = new doc.DynamoDB();
exports.handler = ( event, context, callback ) => {
    const done = ( err, res ) => callback( null, {
        statusCode: err ? '400' : '200',
        body: err ? err.message : JSON.stringify(res),
        headers:{ 'Access-Control-Allow-Origin' : '*' },
    });
    switch( event.httpMethod ) {
        ...
    }
};

Oto moja rozmowa AJAX

$.ajax({
    url: 'https://x.execute-api.x-x-x.amazonaws.com/prod/fnXx?TableName=x',
    type: 'GET',
    beforeSend: function(){ $( '#loader' ).show();},
    success: function( res ) { alert( JSON.stringify(res) ); },
    error:function(e){ alert('Lambda returned error\n\n' + e.responseText); },
    complete:function(){ $('#loader').hide(); }
});
MannyC
źródło
Zauważyłem, że wiele dokumentów Amazona jest nieaktualnych, nawet z fragmentem ścieżki „../latest/ ..”. Po usunięciu wszystkiego około tygodnia temu, przycisk CORS nagle stwierdził, że działa prawidłowo. API automatycznie utworzyło metodę „ANY”, a przycisk CORS automatycznie utworzył metodę „OPTIONS” - ​​nic nie dodałem do API. Powyższe „GET” działa i od tego czasu dodałem „POST” Ajax, który działa również bez dotykania interfejsu API.
MannyC
Spędziłem prawie dwie godziny, próbując dowiedzieć się, jak dodać Access-Control-Allow-Origin do odpowiedzi metody za pomocą konsoli AWS, ale była to również jedyna rzecz, która działała dla mnie.
Shn_Android_Dev
8

Dla pracowników Google:

Oto dlaczego:

  • Proste żądanie lub GET/ POSTbez plików cookie nie powoduje uruchomienia inspekcji wstępnej
  • Podczas konfigurowania CORS dla ścieżki API Gateway utworzy tylko OPTIONSmetodę dla tej ścieżki, a następnie wyśle Allow-Originnagłówki przy użyciu fałszywych odpowiedzi, gdy wywoła użytkownika OPTIONS, ale GET/ POSTnie zostanie Allow-Originautomatycznie
  • Jeśli spróbujesz wysłać proste żądania z włączonym trybem CORS, pojawi się błąd, ponieważ ta odpowiedź nie ma Allow-Originnagłówka
  • Możesz stosować się do najlepszych praktyk, proste żądania nie mają na celu wysyłania odpowiedzi do użytkownika, wysyłania uwierzytelniania / plików cookie wraz z żądaniami, aby uczynić to „nie prostym”, a inspekcja wstępna uruchomi
  • Mimo to będziesz musiał samodzielnie wysłać nagłówki CORS dla następującego żądania OPTIONS

Podsumowując:

  • Tylko nieszkodliwe OPTIONSbędą automatycznie generowane przez API Gateway
  • OPTIONSsą używane przez przeglądarkę tylko jako środek ostrożności do sprawdzenia możliwości CORS na ścieżce
  • To, czy CORS jest akceptowany, zależy od rzeczywistej metody, np. GET/POST
  • W odpowiedzi musisz ręcznie wysłać odpowiednie nagłówki
theaws.blog
źródło
7

Właśnie dodałem nagłówki do mojej odpowiedzi funkcji lambda i zadziałało to jak urok

exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hey it works'),
        headers:{ 'Access-Control-Allow-Origin' : '*' }
    };
    return response;
};
Vishal Shetty
źródło
4

Wewnątrz znalazłem proste rozwiązanie

API Gateway> Select your API endpoint> Select the method (w moim przypadku był to POST)

Teraz jest menu rozwijane DZIAŁANIA> Włącz CORS .. wybierz to.

Teraz ponownie wybierz listę rozwijaną CZYNNOŚCI> Wdróż API (wdróż go ponownie)

wprowadź opis obrazu tutaj

Zadziałało !

Ravi Ram
źródło
Dlaczego ta odpowiedź została odrzucona, ale poniżej są inne podobne odpowiedzi?
Dinesh Kumar
W przypadku wywoływania bramy API opartej na AWS to rozwiązanie działa
ewalel
3

Zacząłem działać po tym, jak zdałem sobie sprawę, że autoryzator lambda zawodzi iz jakiegoś nieznanego powodu został przetłumaczony na błąd CORS. Prosta poprawka do mojego autoryzatora (i kilka testów autoryzacyjnych, które powinienem był dodać w pierwszej kolejności) i zadziałało. Dla mnie była wymagana akcja bramy API „Włącz CORS”. To dodało wszystkie nagłówki i inne ustawienia, których potrzebowałem w moim API.

RodP
źródło
i wdróż ponownie! :)
Robin C Samuel
3

Dla mnie odpowiedzią, która WRESZCIE DZIAŁAŁ, był komentarz Jamesa Shapiro z odpowiedzi Alexa R (druga pod względem popularności). Wpadłem w ten problem z bramą API w pierwszej kolejności, próbując uzyskać statyczną stronę internetową hostowaną w S3, aby użyć lambda do przetworzenia strony kontaktowej i wysłania wiadomości e-mail. Po prostu zaznaczenie [] Default 4XX naprawiło komunikat o błędzie.

wprowadź opis obrazu tutaj

Jason
źródło
Gdzie znajdujesz to menu? Nigdzie tego nie widzę.
Nick H
@NickH spójrz na zdjęcie od Ravi Ram. W sekcji „Działania” powinna znajdować się pozycja „Włącz CORS”, a gdy ją wybierzesz, pojawi się menu.
Jason
2

Po zmianie funkcji lub kodu Wykonaj te dwa kroki.

Najpierw włącz CORS, a następnie wdrażaj interfejs API za każdym razem.

Ankit Kumar Rajpoot
źródło
Dziękuję za to. Nie zauważyłem „Włącz CORS” w zasobie. Sprawił, że straciłem rozum.
Shlomi Bazel
2

Wdrażanie kodu po włączeniu CORS dla obu POSTi OPTIONSdziałało dla mnie.

Ziaur Rahman
źródło
1
Dziękuję za wkład, ale czy możesz wyjaśnić, dlaczego to zadziałało? Zapraszam do przeczytania tego przewodnika, aby poprawić swoją odpowiedź: „Jak piszę dobrą odpowiedź” tutaj: stackoverflow.com/help/how-to-answer
Guillaume Raymond
1

Biegam aws-serverless-express, aw moim przypadku potrzebne do edycji simple-proxy-api.yaml.

Przed skonfigurowaniem CORS-a po https://example.comprostu zamieniłem nazwę mojej witryny i ponownie wdrożyłem za pośrednictwem npm run setup, a także zaktualizowałem moją istniejącą lambdę / stos.

#...
/:
#...
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
/{proxy+}:
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
James L.
źródło
1

W moim przypadku, ponieważ używałem AWS_IAM jako metody autoryzacji dla API Gateway, musiałem przyznać mojej roli IAM uprawnienia do trafienia w punkt końcowy.

CamHart
źródło
2
Człowieku, cieszę się, że zostawiłem ten komentarz. To ciągle mi się przytrafia: D.
CamHart
Uwielbiam znajdować własne rozwiązanie powtarzającego się problemu w przyszłości.
Zac Grierson,
0

Inną główną przyczyną tego problemu może być różnica między protokołami HTTP / 1.1 i HTTP / 2.

Objaw: Niektórzy użytkownicy, nie wszyscy, zgłaszali wystąpienie błędu CORS podczas korzystania z naszego oprogramowania.

Problem:Access-Control-Allow-Origin nagłówek brakowało czasami .

Kontekst: Mieliśmy Lambda na miejscu, przeznaczoną do obsługi OPTIONSżądań i odpowiadania z odpowiednimi nagłówkami CORS, takimi jak Access-Control-Allow-Origindopasowywanie do białej listy Origin.

Rozwiązanie: Brama interfejsu API wydaje się przekształcać wszystkie nagłówki na małe litery dla wywołań HTTP / 2, ale zachowuje wielkość liter w przypadku protokołu HTTP / 1.1. To spowodowało dostęp doevent.headers.origin to niepowodzenie .

Sprawdź, czy też masz ten problem:

Zakładając, że Twój interfejs API znajduje się pod adresem https://api.example.com, a interfejs użytkownika jest pod adresem https://www.example.com. Używając CURL, wyślij żądanie za pomocą HTTP / 2:

curl -v -X OPTIONS -H 'Origin: https://www.example.com' https://api.example.com

Wynik odpowiedzi powinien zawierać nagłówek:

< Access-Control-Allow-Origin: https://www.example.com

Powtórz ten sam krok, używając protokołu HTTP / 1.1 (lub z małym Originnagłówkiem):

curl -v -X OPTIONS --http1.1 -H 'Origin: https://www.example.com' https://api.example.com

Jeśli Access-Control-Allow-Originbrakuje nagłówka, możesz chcieć sprawdzić wielkość liter podczas czytania Originnagłówka.

Michael Seibt
źródło
0

Oprócz innych komentarzy, należy zwrócić uwagę na stan zwrócony z podstawowej integracji i czy dla tego statusu zostanie zwrócony nagłówek Access-Control-Allow-Origin.

Wykonanie czynności „Włącz CORS” powoduje ustawienie tylko 200 statusu. Jeśli masz inne punkty końcowe, np. 4xx i 5xx, musisz samodzielnie dodać nagłówek.

Nigel Atkinson
źródło
-2

W moim przypadku po prostu wpisałem nieprawidłowy adres URL żądania pobrania. On serverless.ymlmożna ustawić corsna true:

register-downloadable-client:
    handler: fetch-downloadable-client-data/register.register
    events:
      - http:
          path: register-downloadable-client
          method: post
          integration: lambda
          cors: true
          stage: ${self:custom.stage}

a następnie w module obsługi lambda wysyłasz nagłówki, ale jeśli wykonasz błędne żądanie pobierania na interfejsie użytkownika, nie otrzymasz tego nagłówka w odpowiedzi i otrzymasz ten błąd. Dlatego dokładnie sprawdź adres URL swojego żądania z przodu.

Ericson Willians
źródło
-3

W Pythonie możesz to zrobić jak w poniższym kodzie:

{ "statusCode" : 200,
'headers': 
    {'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': "*"
     },
"body": json.dumps(
    {
    "temperature" : tempArray,
    "time": timeArray
    })
 }
Mukesh Arya
źródło