AWS API Gateway endpoint gives CORS error when POS

2020-02-10 03:21发布

问题:

I have created an API endpoint with Serverless(serverless.com) which I expose through API Gateway. I'm getting following error though I have enabled CORS from the

XMLHttpRequest cannot load https://xxxxxxxxx.execute-api.us-west-2.amazonaws.com/development/signup. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://yyyyyyyyy.com.s3-website-us-east-1.amazonaws.com' is therefore not allowed access.

I don't get any errors when I use Postman to make requests, despite I have set origin header or not. How can I fix this problem?

回答1:

We have a bug right now where failed requests to API Gateway won't include the appropriate CORS headers, which masks the actual error on the request.

I'd add to what Ken said and make sure you've thoroughly tested the API and resources in the console and also on the deployed version using Postman or some other client that isn't a browser. I expect there is an issue with the API itself and that your CORS configuration is correct.



回答2:

As Jack Kohn pointed out the AWS console does not add the CORS headers on non 200 response, and apparently does not allow you to add any custom header.

I was able to enable CORS headers on failed request by exporting to swagger and manually editing the file (Just copied the 200 response) and importing it back.

The responses should look like this:

  responses:
    200:
      description: "200 response"
      schema:
        $ref: "#/definitions/Empty"
      headers:
        Access-Control-Allow-Origin:
          type: "string"
    401:
      description: "401 response"
      schema:
        $ref: "#/definitions/Empty"
      headers:
        Access-Control-Allow-Origin:
          type: "string"
  x-amazon-apigateway-integration:
    responses:
      default:
        statusCode: "200"
        responseParameters:
          method.response.header.Access-Control-Allow-Origin: "'*'"
        responseTemplates:
          application/json: "__passthrough__"
      Authentication Failed.*:
        statusCode: "401"
        responseParameters:
          method.response.header.Access-Control-Allow-Origin: "'*'"
        responseTemplates:
          application/json: "__passthrough__"

Hope this helps.



回答3:

I would start troubleshooting by inspecting your API in the AWS Console to make sure serverless registered everything the way you expect.

  1. Load the AWS Console and navigate to the API Gateway service.
  2. Click the API to open it up.
  3. Find your /signup resource
  4. Make sure you see the OPTIONS method under /signup
  5. Click each resource including options and check the following:

    a. Click Integration Response, click the arrow in the first row of the table for 200 to open it up.

    b. Click the arrow to open Header Mappings

    c. Make sure you see Access-Control-Allow-Origin mapped to '*'

If you find this header missing from one of the methods a quick fix is to click back on the /signup Resource and click the Enable CORS button. AWS will build out OPTIONS and the header mappings on all methods for you. Of course you still need to figure out why serverless didn't set things up for you but this will at least get you going.

Another note about the Enable CORS button, if you add another method later you'll have to click it again to re-run the tool to setup your new method with CORS.



回答4:

I was struggling with the same issue when 'POST' to API Gateway. But I found the fix for the issue.

After enabling CORS for the method resource, and after adding the necessary Headers e.g. 'Access-Control-Allow-Origin' = '*' wildcard, and it still fails.

Go to OPTIONS of that resource you are invoking, 'GET', 'POST', etc..click the "Method Request" pane of that resource, set API Key = FALSE, do NOT have the API Key set to true. This will cause the CORS error.

Reason, OPTIONS is technically not a method, it a browser function to execute the Preflight request, thus during the Preflight the browser does not know what API key to send, it will know only know after the response is return to the browser of 'Access-Control-Allow-Origin' = '*' then it will look up the code for the HTTP req to setHeaders of the X-Api-Key = some value.

Note: the invoke method itself, 'POST', etc.. can have the API Key = True, which is perfectly fine.

Hope this help those who are struggling as I did for a while :)



回答5:

I have the this problem...I enable CORS, the Test work as it is sending the headers, but when I call it from my app it fails and no headers found on the response.

it is because after set CORS you have to DEPLOY the API. I Deplyed the API and everything works great.



回答6:

Response should have, If you are using AWS lamda, set response headers as follows. Configuration on API Gateway only will not work

headers: {
            'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*',
        },


回答7:

I had near the same problem,as i posted in another question, I needed to add the following headers to my response:

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'
        }

And , according to this documentation:

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

When you use proxy for lambda functions on API Gateway config, the post or get methods have no added headers, only the options method does. You must do it manually in the response(server or lambda response).

Beside that, I needed to disable the 'API Key Required' option in my API gateway post method, as someone here already said.



回答8:

You need to enable CORS for all the methods. Means, you need to add below three headers for all your methods

            "headers": {
            "Access-Control-Allow-Origin": {
                "type": "string"
            },
            "Access-Control-Allow-Methods": {
                "type": "string"
            },
            "Access-Control-Allow-Headers": {
                "type": "string"
            }
        }

It is tedious task to add these headers to all your methods in JSON.

Created a utility in Java which automatically adds these headers to Swagger JSON. You can run it before importing it to API Gateway and import the output JSON which has CORS enabled in all the methods

https://github.com/anandlalvb/SwaggerToAPIGateway

I hope this utility may help anyone looking for this to do it easily.



回答9:

I am using AWS sdk for uploads, after spending some time searching online i stumbled upon this thread. thanks to @lsimoneau 45581857 its turns out the exact same thing was happening. I simply pointed my request Url to the region on my bucket by attaching the region property and it worked.

 const s3 = new AWS.S3({
 accessKeyId: config.awsAccessKeyID,
 secretAccessKey: config.awsSecretAccessKey,
 region: 'eu-west-2'  // add region here });