AWS API Gateway with Angular

15,348

Solution 1

Api Gateway team here.

Hopefully by now you've checked out the new 'Enable CORS' feature in the console. Even if your dev workflow is outside the console, you could quickly setup a test API and look at the header configurations that the console sets up for you, then copy those to your Swagger def or whatever solution you've come up with.

The docs guide should still apply in either case. You'll need the 3 headers: Access-Control-Allow-Methods, Access-Control-Allow-Origin, and Access-Control-Allow-Headers. The values of these will depend on your API.

If you'd like to send me the API resource you're trying to invoke, I can take a look from our side.

Solution 2

I've currently got a POST function working via API Gateway and Lambda that is accessed from an Angular client with CORS. While I don't know what your configuration is, I can share all of my relevant settings in the hopes that maybe you find something you missed. Enabling CORS is quite a pain at the moment (and hopefully something that Amazon is working on fixing) requiring a lot of little steps in a lot of areas with fairly poor documentation.

I have 2 methods (OPTIONS and POST) for my resource and I'll share the relevant settings for each:

POST:
Method Request: Nothing special. In the case of my endpoint, I have an option under Request Paths for one of my route parameters. I'm not using a query string, so URL Query String is empty. HTTP Request Headers is empty as well.

Integration Request:
Integration Type: Lambda Mapping Templates: I have one (application/json) with a template to pass the appropriate values from the request body and route parameters to my lambda function.

Method Response:
Expand the 200 status code field. Add a header for "Access-Control-Allow-Origin" and click the check mark button to save it. You might have to do this for any other status codes you might have.

Integration Response:
Expand the 200 response status field. Under Header Mappings, modify the mapping value to contain '*'. The single quotes are required. You might have to do this for any other integration responses you might have.

OPTIONS:
Method Request:
Nothing special, just like the POST method.

Integration Request:
I have it set to mock integration. According to Amazon, it doesn't matter, so I just set it to mock as all we really need to do is respond 200 with the appropriate headers. No mapping templates.

Method Response:
Expand the 200 status code field. Add the following 3 response headers and save them with the check box: Access-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Origin. There are no other status codes present.

Integration Response:
Expand the 200 response status field. The regex is empty (set to default) and this method only has a 200 response. Expand header mappings and set the headers to the following mapping values:

Access-Control-Allow-Headers: 'Content-Type,X-Amz-Date,Authorization,X-Requested-With'
Access-Control-Allow-Methods: 'GET,POST,OPTIONS'    
Access-Control-Allow-Origin:  '*'

There are no mapping templates.

Then deploy your API. Hopefully it now allows CORS requests. I encountered the exact same issue you did, and I'm fairly certain that the problem was missing the X-Requested-With value in Access-Control-Allow-Headers.

Solution 3

TLDR; It's not CORS issue, the issue come from the API Gateway, check issue on your API handler on API Gateway. Make sure that your API can works with Postman before use it inside your UI project.

You can follow this guideline how to CORS. But looks like you've already did this action.

Let's talk about CORS first: this is a mechanism that help you to protect your customer when they using your web application, allow you to config response headers so that:

  • Other hosts can access to the resources of your web application. For example: Access-Control-Allow-Origin: abc.com, when you return a response with this header. This will allow requests from host abc.com.
  • Restrict the accessible to specifics HTTP methods. For example: Access-Control-Allow-Methods: GET, PUT, only allow origin to access resources with method GET or PUT, not allow POST, DELETE or any other methods.
  • Only allow requests have headers that match with your defined list. Access-Control-Allow-Headers: Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token, some of these headers are defined by Amazon, you actually can specify your own headers.

You should consider to set the value for those attribute. With my opinion is just use * (Access-Control-Allow-Origin: *) when you're developing and change the value to specific domain or wildcard (Access-Control-Allow-Origin: *.abc.com) when you publish your API.

And here is how CORS works:

enter image description here

As you can see here, before your actual request sent to API Gateway, your browser sent an OPTIONS request to API Gateway to make sure that your request is allowed to send to API Gateway. If OPTIONS request return 200, then your actual request will be send to API Gateway.

  1. If your OPTIONS request is failed. Then your request can't be sent to API Gateway. And in the Developer Tools you'll see something like No 'Access-Control-Allow-Origin' is present on the requested resource... but there are no more error message. The request will return status is 0 -> You have to config CORS.

  2. One another case is the same as you explain on your question. Got HTTP Status Code 500, and something about CORS also. This is not CORS problem, it's browser problem I think. In this case, OPTIONS request return status code 200. Your actual request return status code 500, that's mean your API broken already. Browser still send No 'Access-Control-Allow-Origin' is present on the requested resource... error. In this case, you have to debug your API to see the issue.

Hope that helps!

Solution 4

You can 'Enable CORS' feature from AWS API Gateway. Login to your AWS account and navigate to API Gateway. Choose a resource under Resources and choose enable CORS from the actions drop-down menu. This will enable CORS for all the methods on the resource. Please check below link for detail

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

Share:
15,348
Kristóf Horváth
Author by

Kristóf Horváth

Updated on June 05, 2022

Comments

  • Kristóf Horváth
    Kristóf Horváth almost 2 years

    Has anyone gotten the AWS API Gateway to work with an Angular.js front-end? I have a lambda function that's exposed via a POST method in the API Gateway. I set up the headers as indicated by this doc: http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html

    I tested it in Postman and it works great. I didn't have to do anything special, but when I do the $http.post() call I only get No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin http://localhost:9000 is therefore not allowed access. The response had HTTP status code 500. as the response.

  • Chalise
    Chalise over 8 years
    This answer is perfect. The "Enable CORS" button in the console is overriding everything saved at the moment. I have a ticket in with support, but until that is fixed this works.
  • Mike
    Mike about 8 years
    If you make a video tutorial of this I will give you $20 in Bitcoin
  • turiyag
    turiyag almost 8 years
    I just spent an hour trying to figure out why your document didn't work, and it wasn't actually your document's fault, it was that I didn't Deploy the API afterward. Can you consider putting that in your document: docs.aws.amazon.com/apigateway/latest/developerguide/…
  • rex
    rex over 7 years
    Bloody hell thanks mate thanks! Been on this for a few hours now... turns out I had to DEPLOY the api. Strange that I didn't have to do that when making other changes! :/
  • Dave Maple
    Dave Maple over 7 years
    haha. funny -- but i've helped troubleshoot that exact issue several times recently. we still do have to remember to deploy the code :)
  • Avinash
    Avinash about 4 years
    @Akshay Dhalwala With your changes I am able to solve the CORS problem, but now getting 401 - Unauthorized error. The API Gateway service is integrated with the AWS Cognito service where I have enabled the Authorization for the 'GET' method. I also have added the X-Requested-With option in 'Access-Control-Allow-Headers' and redeployed it. Please let me know how I can solve the 401 issue.