API Gateway CORS : 'Access-Control-Allow-Origin'헤더 없음


106

CORS가 API Gateway를 통해 설정되고 Access-Control-Allow-Origin헤더가 설정되었지만 Chrome 내 AJAX에서 API를 호출하려고하면 여전히 다음 오류가 발생합니다.

XMLHttpRequest는 http://XXXXX.execute-api.us-west-2.amazonaws.com/beta/YYYYY를 로드 할 수 없습니다 . 요청 된 리소스에 'Access-Control-Allow-Origin'헤더가 없습니다. 따라서 Origin 'null'은 액세스가 허용되지 않습니다. 응답에 HTTP 상태 코드 403이 있습니다.

Postman을 통해 URL을 얻으 려고 시도했는데 위의 헤더가 성공적으로 전달되었음을 보여줍니다.

전달 된 헤더

그리고 OPTIONS 응답에서 :

응답 헤더

JSON-P로 되 돌리지 않고 브라우저에서 API를 호출하려면 어떻게해야합니까?


S3에 설정되어 있습니까? 그렇다면 Bucket Policy? 정책에 방법이 있는지 확인하십시오
iSkore

12
여기에 API Gateway 팀 ... 콘솔에서 'CORS 활성화'기능을 사용하는 경우 구성이 정확해야합니다. 내 최선의 추측은 브라우저가 실행하는 JavaScript의 API에서 올바른 리소스 경로를 호출하지 않는 것입니다. 존재하지 않는 메서드 / 리소스 / 스테이지에 대한 API 호출을 시도하면 CORS 헤더가없는 일반 403을 받게됩니다. Postman의 OPTIONS 호출에 올바른 CORS 헤더가 모두 포함되어 있기 때문에 올바른 리소스를 호출하는 경우 브라우저가 Access-Control-Allow-Origin 헤더를 놓칠 수있는 방법을 알 수 없습니다.
jackko

1
@ RyanG-AWS는 API가 사용자 별 토큰을 사용하여 호출하는 리소스에 의해 인증되기 때문에 클라이언트가 요청에 서명하지 않으므로 자격 증명은 요소가 아닙니다. 브라우저에서 직접 URL을 방문하여 API를 호출 할 수 있으며 적절한 응답을받습니다.
Tyler

2
@makinbacon : 이에 대한 해결책을 찾았습니까? 여기서도 같은 문제를 겪고 있습니다.
Nirmal

1
내 메서드와 단계는 Lambda에 의해 자동으로 생성되었습니다. 사실 후에 CORS를 활성화했습니다. OP와 동일한 오류입니다. 나는 자동 생성 된 것들을 날려 버리고, 새로운 API와 메소드를 만들고, 새로운 단계에 배포했고, 잘 작동했습니다.
데게

답변:


125

나는 같은 문제가 발생합니다. 나는 10 시간을 사용했다.

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

내가 가지고 있던 문제도 수정했습니다. 답변 주셔서 감사합니다!
Eric Brown

나는 서버리스를 사용하지 않지만 이것이 내 문제를 해결했습니다. 실제 소스에서 이러한 헤더를 전달해야한다고 생각합니다.
Costa

2
참고로 여기에 제시된 예에 문제가 있습니다. "Access-Control-Allow-Credentials": true가있는 경우 Access-Control-Allow-Origin에 와일드 카드 *를 사용할 수 없습니다. 이 규칙은 브라우저에서 적용됩니다. 참조 여기여기에
케빈

1
이것은 작동하지 않습니다. 다시 동일한 오류가 표시됩니다. 요청 헤더 필드 access-control-allow-credentials is not allowed by Access-Control-Allow-Headers in preflight response.
mitesh7172

1
궁금한 사람을위한 공식 문서는 다음과 같습니다. docs.aws.amazon.com/apigateway/latest/developerguide/… > Lambda 또는 HTTP 프록시 통합의 경우 API Gateway에서 필수> OPTIONS 응답 헤더를 설정할 수 있습니다. 그러나 프록시 통합에 대해> 통합 응답이 비활성화되어 있으므로> 백엔드를 사용하여 Access-Control-Allow-Origin 헤더를 반환해야합니다.
Leonid Usov

109

다른 사람이 여전히이 문제를 겪고 있다면 응용 프로그램에서 근본 원인을 추적 할 수있었습니다.

사용자 지정 권한 부 여자와 함께 API-Gateway를 실행하는 경우 API-Gateway는 실제로 서버에 도달하기 전에 401 또는 403을 다시 보냅니다. 기본적으로 API-Gateway는 사용자 지정 권한 부 여자에서 4xx를 반환 할 때 CORS에 대해 구성되지 않습니다.

또한 -API Gateway를 통해 실행되는 요청에서 상태 코드를 0받거나 1받는 경우 이는 아마도 문제 일 수 있습니다.

수정하려면-API Gateway 구성에서- "Gateway Responses"로 이동하여 "Default 4XX"를 확장하고 거기에 CORS 구성 헤더를 추가합니다. 즉

Access-Control-Allow-Origin: '*'

게이트웨이를 다시 배포해야합니다 .


7
사랑해. 이틀 동안 진지하게 작업했습니다.
efong5

4
AWS CLI를 사용하여이 작업을 수행하려는 경우 다음을 사용하십시오.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
사용자 지정 권한 부여자를 사용하지 않고 내 요청에 잘못된 JSON이 포함되어 있으므로 여전히 필요합니다. 감사합니다!
Force Hero

9
나 자신에게 메모-나중에 API를 배포하는 것을 잊지 마십시오 :)
danieln

2
이상합니다. 이것은 저에게 효과적이지만 재배포 할 필요가 없었습니다. 이전에 재배포를 시도했습니다. 왜 그것이 나를 위해 일했는지 잘 모르겠습니다.
Michael

19

1) @riseres 및 기타 변경 사항과 동일한 작업을 수행해야했습니다. 이것은 내 응답 헤더입니다.

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) 그리고

이 문서에 따르면 :

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

API Gateway 구성에서 람다 함수에 프록시를 사용하는 경우 post 또는 get 메서드에 추가 된 헤더가없고 옵션 만 있습니다. 응답 (서버 또는 람다 응답)에서 수동으로 수행해야합니다.

3) 그리고

그 외에도 API 게이트웨이 게시 방법에서 'API 키 필요'옵션을 비활성화해야했습니다.


5
네, 우리가 처음에 놓친 미묘한 점은 "Lambda 프록시 통합 사용"을 사용하여 Lambda 함수에 대한 API 게이트웨이 통합을 구성한 다음에는 자신과 다른 사람들이 언급 한대로 수행하고 헤더가 추가되었는지 확인해야한다는 것입니다. 람다의 응답에서 프로그래밍 방식으로. API 게이트웨이에서 "CORS 활성화"및 OPTIONS 응답자를 생성하여 생성 된 자동 생성 항목은 훌륭하지만 API 내의 통합 요청에서 "Lambda 프록시 통합 사용"을 설정하면 모든 작업을 수행 할 수 없습니다. 게이트웨이.

1
이것은 나를 위해 일했습니다 ... 매뉴얼을 올바르게 읽은 후 : 중요 프록시 통합의 모든 방법에 위의 지침을 적용하면 적용 가능한 CORS 헤더가 설정되지 않습니다. 대신 백엔드는 Access-Control-Allow-Origin과 같은 적용 가능한 CORS 헤더를 반환해야합니다. docs.aws.amazon.com/apigateway/latest/developerguide/...
BennyHilarious

19

이 문제에 관한 모든 것을 시도해도 소용이 없다면 내가 한 곳으로 끝날 것입니다. Amazon의 기존 CORS 설정 지침은 정상적으로 작동합니다. 재배포하는 것을 잊지 마십시오 ! CORS 편집 마법사는 작은 녹색 확인 표시가 모두 있어도 API를 실시간으로 업데이트하지 않습니다. 당연한 것 같지만 반나절 동안 나를 괴롭혔다.

여기에 이미지 설명 입력


2
그게 다야. 말 그대로 이틀 동안 작업했습니다. 게이트웨이를 편집 한 후 적어도 재배포를 요구하지 않는 논리가 확실하지 않습니다.
Chris Christensen

@ChrisChristensen 당신이 그것을 알아 낸 것을 기뻐합니다-항상 이와 같은 문제에 대해 너무나도 안심할 수 있지만 믿을 수 없을 정도로 패배하는 것이 있습니다
lase

이것이 2020 년에 유효한 답변입니다. 감사합니다
Rahul Khanna

1
RE-DEPLOY RE-DPLOY 재배포
Surjith SM

12

샘플 작동 : 방금 생성 된 nodejs Lambda 함수의 headers : {} 안에 'Access-Control-Allow-Origin': '*'를 삽입했습니다 . 나는하지 아니 람다 생성 된 API 레이어로 변경.

내 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 ) {
        ...
    }
};

다음은 내 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(); }
});

"../latest/ .."경로 조각이 있더라도 많은 Amazon 문서가 최신이 아님을 발견했습니다. 약 일주일 전에 모든 것을 스크랩 한 후 CORS 버튼이 갑자기 제대로 작동한다고 말했습니다. API는 "ANY"메소드를 자동으로 생성했고 CORS 버튼은 "OPTIONS"메소드를 자동으로 생성했습니다. API에 아무것도 추가하지 않았습니다. 위의 "GET"이 작동하고 API를 건드리지 않고도 작동하는 ajax "POST"를 추가했습니다.
MannyC

AWS 콘솔을 사용하여 메서드 응답에 Access-Control-Allow-Origin을 추가하는 방법을 알아 내기 위해 거의 2 시간을 보냈지 만 이것이 저에게 효과적이었습니다.
Shn_Android_Dev

8

Google 직원 :

그 이유는 다음과 같습니다.

  • 간단한 요청 또는 GET/ POST쿠키가없는 경우 프리 플라이트를 트리거하지 않습니다.
  • 경로에 대한 CORS를 구성하면 API Gateway는 OPTIONS해당 경로에 대한 메서드 만 생성 한 다음 Allow-Origin사용자가 호출 할 때 모의 응답을 사용하여 헤더 를 전송 OPTIONS하지만 GET/ POSTAllow-Origin자동으로 가져 오지 않습니다.
  • CORS 모드가 켜진 상태에서 간단한 요청을 보내려고하면 해당 응답에 Allow-Origin헤더 가 없기 때문에 오류가 발생합니다.
  • 모범 사례를 준수 할 수 있습니다. 단순 요청은 사용자에게 응답을 보내는 것이 아니라 인증 / 쿠키를 "간단하지 않은"요청과 함께 전송하고 프리 플라이트가 트리거됩니다.
  • 그래도 다음 요청에 대해 CORS 헤더를 직접 보내야합니다. OPTIONS

그것을 요 ​​약하기:

  • OPTIONSAPI Gateway에 의해 무해한 것만 자동으로 생성됩니다.
  • OPTIONS브라우저 에서 경로에서 CORS 가능성 을 확인하기위한 신중한 조치로만 사용됩니다.
  • CORS 허용 여부 는 실제 방법 (예 : GET/POST
  • 응답에 적절한 헤더를 수동으로 보내야합니다.

7

방금 람다 함수 응답에 헤더를 추가했는데 매력처럼 작동했습니다.

exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hey it works'),
        headers:{ 'Access-Control-Allow-Origin' : '*' }
    };
    return response;
};

4

내에서 간단한 해결책을 찾았습니다.

API Gateway> API 엔드 포인트 선택> 방법 선택 (제 경우에는 POST)

이제 드롭 다운 작업> CORS 활성화 .. 선택하십시오.

이제 드롭 다운 작업을 다시 선택> API 배포 (다시 배포)

여기에 이미지 설명 입력

작동했습니다!


이 답변이 반대표를 받았지만 다른 유사한 답변이 아래에있는 이유는 무엇입니까?
Dinesh Kumar

AWS 기반 API 게이트웨이 호출의 경우이 솔루션이 작동합니다
ewalel

3

람다 작성자가 실패하고 CORS 오류로 변환되는 알 수없는 이유로 인해 작업을 수행했습니다. 내 작성자에 대한 간단한 수정 (그리고 처음에 추가해야하는 일부 작성자 테스트)이 작동했습니다. 나를 위해 API 게이트웨이 작업 'CORS 활성화'가 필요했습니다. 이것은 API에 필요한 모든 헤더 및 기타 설정을 추가했습니다.


그리고 다시 배포하십시오! :)
Robin C Samuel

3

저에게있어서 최종적으로 작업 한 답변은 Alex R의 답변 (두 번째로 많은 찬성)에서 James Shapiro의 댓글이었습니다. 처음에는 S3에서 호스팅되는 정적 웹 페이지를 가져 와서 람다를 사용하여 연락처 페이지를 처리하고 이메일을 보내려고 시도함으로써이 API 게이트웨이 문제에 직면했습니다. [] 기본값 4XX를 선택하기 만하면 오류 메시지가 수정되었습니다.

여기에 이미지 설명 입력


이 메뉴는 어디에 있습니까? 나는 그것을 어디에도 보지 않는다.
Nick H

@NickH는 Ravi Ram의 사진을 봅니다. "Actions"아래에 "Enable CORS"라는 항목이 있어야하며이를 선택하면 메뉴가 표시됩니다.
제이슨

2

기능 또는 코드를 변경 한 후 다음 두 단계를 따르십시오.

먼저 CORS를 활성화 한 다음 매번 API를 배포합니다 .


감사합니다. 리소스에서 "CORS 활성화"를 인식하지 못했습니다. 정신을 잃게 만들었습니다.
Shlomi Bazel

2

모두 CORS를 활성화 한 후 코드를 배포 POST하고 OPTIONS나를 위해 일했습니다.


1
기여 해주셔서 감사합니다.하지만 왜 그것이 당신에게 도움이되었는지 설명해 주시겠습니까? 답변을 개선하기 위해이 가이드를 읽어 보시기 바랍니다. "내가 좋은 답변을 작성하는 방법": stackoverflow.com/help/how-to-answer
Guillaume Raymond

1

나는 달리고있다 aws-serverless-express 내 경우에는 편집해야합니다 simple-proxy-api.yaml.

CORS가로 구성되기 전에 https://example.com방금 내 사이트 이름을 바꾸고를 통해 재배포 npm run setup했으며 기존 람다 / 스택을 업데이트했습니다.

#...
/:
#...
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
/{proxy+}:
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...

1

제 경우에는 API Gateway에 대한 권한 부여 방법으로 AWS_IAM을 사용하고 있었기 때문에 엔드 포인트에 도달 할 수있는 IAM 역할 권한을 부여해야했습니다.


2
이 댓글을 남겨 주셔서 감사합니다. 이것은 나에게 계속 일어나고 있습니다 : D.
CamHart

나는 미래의 반복되는 문제에 대한 나만의 해결책을 찾는 것을 좋아합니다.
Zac Grierson

0

이 문제의 또 다른 근본 원인은 HTTP / 1.1과 HTTP / 2의 차이 일 수 있습니다.

증상 : 모두가 아닌 일부 사용자가 소프트웨어를 사용할 때 CORS 오류가 발생한다고보고했습니다.

문제 :Access-Control-Allow-Origin 헤더가 누락 된 가끔 .

컨텍스트 :OPTIONS 요청 을 처리 하고 해당 CORS 헤더로 응답하는 데 전념하는 Lambda가 준비되어 있습니다 (예 : Access-Control-Allow-Originwhitelisted Origin.

솔루션 : API Gateway는 HTTP / 2 호출의 경우 모든 헤더를 소문자로 변환하는 것처럼 보이지만 HTTP / 1.1의 경우 대문자를 유지합니다. 이로 인해 액세스 event.headers.origin가 실패했습니다.

이 문제가 있는지 확인하십시오.

API가에 https://api.example.com있고 프런트 엔드가에 있다고 가정합니다 https://www.example.com. CURL을 사용하여 HTTP / 2를 사용하여 요청합니다.

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

응답 출력에는 헤더가 포함되어야합니다.

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

HTTP / 1.1 (또는 소문자 Origin헤더)을 사용하여 동일한 단계를 반복합니다 .

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

경우 Access-Control-Allow-Origin헤더가없는, 당신은 읽을 때 대소 문자 구분을 확인 할 수 있습니다 Origin헤더를.


0

다른 의견 외에도 기본 통합에서 반환 된 상태와 해당 상태에 대해 Access-Control-Allow-Origin 헤더가 반환되는지 확인해야합니다.

'CORS 활성화'작업을 수행하면 상태가 200 개만 설정됩니다. 엔드 포인트에 다른 사용자 (예 : 4xx 및 5xx)가있는 경우 헤더를 직접 추가해야합니다.


-2

제 경우에는 단순히 가져 오기 요청 URL을 잘못 작성했습니다. 에 serverless.yml, 당신은 설정 cors합니다 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}

그런 다음 람다 처리기에서 헤더를 보내지 만 프런트 엔드에서 가져 오기 요청을 잘못하면 응답에서 해당 헤더를 얻지 못하고이 오류가 발생합니다. 따라서 전면에서 요청 URL을 다시 확인하십시오.


-3

Python에서는 아래 코드와 같이 수행 할 수 있습니다.

{ "statusCode" : 200,
'headers': 
    {'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': "*"
     },
"body": json.dumps(
    {
    "temperature" : tempArray,
    "time": timeArray
    })
 }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.