CORS request did not succeed - Cloudfront and ELB over HTTPS - amazon-web-services

When we access backend api of ELB an https url, throws an error
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://abcde-1xx8x3xx3x.ap-south-1.elb.amazonaws.com/api/auth/testapi. (Reason: CORS request did not succeed).
Frontend:
We are using Cloudfront to deliver frontend from S3. The cloudfront URL link works and the page loads fine.
On cloudfront side in behaviour section,
whitelisted the headers [Accept, Access-Control-Allow-Origin, Access-Control-Request-Headers, Access-Control-Request-Method, Authorization, Content-Type, Referer, X-Access-Token, X-HTTP-Method-Override, X-Requested-With]
Viewer Prorocol Policy - Redirect HTTP to HTTPS
Allowed HTTP Methods - GET, HEAD, OPTIONS, PUT, POST.....
Backend:
Backend nodejs rest api is in EC2 and delivered via Classic Load Balancer internet facing. EC2 is within VPC. We are using ELB URL for API testing. The API works in Postman. Here, we have used Load balancer protocol as HTTPS and instance protocol as HTTP. There is a SSL certificate attached to this.
on the nodejs application, we are setting headers as below
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Request-Method', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.header('Access-Control-Allow-Headers','Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, Access-Control-Allow-Origin, Origin, X-HTTP-Method-Override, Accept, X-Access-Token');
res.setHeader('Access-Control-Allow-Credentials', 'true');
on the fontend code while using fetch api, we are setting mode: 'cors'
Tried looking in to other similar cors issues, but nothing helped.
Can anyone suggest me on how to solve this cors issue, what am i missing here? Or is there a better way to handle this for production?

This isn't actually a CORS error. It's a connectivity problem that happens to involve a CORS request.
Reason: CORS request did not succeed
The HTTP request which makes use of CORS failed because the HTTP connection failed at either the network or protocol level. The error is not directly related to CORS, but is a fundamental network error of some kind.
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSDidNotSucceed
You have presumably modified the URL https://abcde-1xx8x3xx3x.ap-south-1.elb.amazonaws.com/api/auth/testapi somewhat, but note that it is impossible to use HTTPS on a URL ending with .elb.amazonaws.com. This is because it is impossible to get an SSL certificate for an amazonaws.com domain name -- that is Amazon's domain name, not your domain name. You can't get an SSL certificate for a domain you don't really control. You need your own domain, here, and an SSL certificate to match it, attached to the balancer.
You should find that by punching this API URL directly into the address bar of your browser, you also get an error. That error will not be a CORS error, and it is the actual error that you need to resolve.
Note also that your S3 and CloudFront settings are not involved in the error you have described.

Related

API Gateway Redirect http to https

We are using AWS API Gateway with a custom domain. When we try https: it works fine. But we try http:
We CloudFront distribution, with configurations:
Origin Domain Name:
Minimum Origin SSL Protocol: TLSv1.2
Origin Protocol Policy: HTTPS
Viewer Protocol Policy: Redirect HTTP to HTTPS
Allowed HTTP Methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
With this, it redirects all the GET requests from HTTP to HTTPS.
But if we send a POST request to https://, cloudfront doesn't redirect and it just throws an error.
We need a way to redirect http: requests to https: for the API gateway
This behaviour of cloudfront is explained in this post redirect-http-requests-to-https-on-aws-api-gateway-using-custom-domains
quoting from the post
There is not a particularly good way to do this for APIs in general, because redirection of a POST request from HTTP to HTTPS is actually a little bit pointless -- the data have already been sent insecurely by the time the redirect is generated, unless the client has asked the server to inspect the request headers before the body is sent, with Expect: 100-continue.
You can create a CloudFront distribution, and configure it to redirect GET and HEAD requests from HTTP to HTTPS... but if you send a POST request to such distribution, CloudFront doesn't redirect -- it just throws an error, since (as noted) such redirection would be more harmful than helpful.

Cloudfront X-Cache shows "Miss from cloudfront" all the time

I have a cloudfront web distribution setup for an API Gateway proxy. The API is IAM enabled mock call. I also created a customer name which has the same domain name as the cname I used to create cloudfront distribution. I set cloudfront up to pass Authorization and Host only for headers. And set Query String forwarding and Forward Cookie to None.
When I hit the cloud front using Postman, I kept on getting Miss from cloudfront from the response. I also disabled Postman's send no-cache header and I also tried manually adding a Cache-Control: max-age=3600.
But None of these works.
Anyone knows why?
I just solved a similar issue by noticing that the API Gateway domain name for my RestAPI was always returning an X-Cache header with "Miss from cloudfront"; but after realizing I had used the execute api domain, my second request to my *.cloudfront.net domain resulted in a Cloudfront cache hit.

AWS CloudFront return 404 after forwarding cookies

I'm trying to setup load balancer for multiple services. Each service has own external ELB.
I don't want to use subdomains for service1, service2... because of the CORS and want to get rid of OPTIONS request.
I'm using CloudFront and Behaviors for that. Website is a SPA.
https://beta.myapp.com - main page → S3
https://beta.myapp.com/api/service1/v1/* → service1 ELB
https://beta.myapp.com/api/service2/v1/* → service2 ELB
When I setup behavior for service1 without any forwarding I'm geting error from my service - 401 Unauthorized. Because it's rely on the cookie for unauthorization.
After I'm set Forward Cookies - All or Whitelist myapp-api-token* - I start getting 404 error and redurect to my error static page. I don't see in the service logs that my service was requested.
The other options like Cache Based on Selected Request Headers and Query String Forwarding and Caching not affecting anything at all.
What might be a problem?
How to debug or log routing in CloudFront?
Might be important to mention that cookie is Secured and HttpOnly.
Example of the cookie:
cookie: myapp-api-token=eyJraWQiOiJyRlZYTGpCRVJJRDZ6MVVpSVpDaENVQVczNlRua0FMb3dDQzlHMnBmcG1VPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJiZGYzNjNiOC1jMWM3LTQzNDMtOTc2My0zOTk3ZDFiNTYxZWQiLCJjdXN0b206a2V5U3BlYyI6IkFFU18yNTYiLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAudXMtZWFzdC0xLmFtYXpvbmF3cy5jb21cL3VzLWVhc3QtMV9FRzlwSjRsb0giLCJjdXN0b206ZW5jcnlwdGVkUGFzc3dvcmQiOiJBUUVDQUhqa3BxM0pmUzNId0c1XC92cTNicHY4TUdjaWhJZ0hReVFsQk1OY09Ea1JZOHdBQUFIb3dlQVlKS29aSWh2Y05BUWNHb0dzd2FRSUJBREJrQmdrcWhraUc5dzBCQndFd0hnWUpZSVpJQVdVREJBRXVNQkVFREo5b2hwYSt2WnNMdXBQXC9sQUlCRUlBM3RCOUFrRWhjR0hJSFhiSitnXC9DRUZ3REljc3EzaEpBTVlxTVZmS2g1ZmZIVW9BMGp2YzU2NzJGcEpjK3BWbzdTMytZXC9nWVdqMnc9PSIsImNvZ25pdG86dXNlcm5hbWUiOiJDTE9VREZMT1ctdXMtZWFzdC0xOjAxNDE4ZDJhLWJlZGYtNDgzYy05NjFlLWE0YjQ5MjRhNjhkZCIsInByZWZlcnJlZF91c2VybmFtZSI6IkNMT1VERkxPVy11cy1lYXN0LTE6M2VmZjBmYWItN2RiZC00YjhjLTk0YmMtMjZkZDIyODIyY2IyIiwiYXVkIjoiM3A5aHMxc2VrOGo0OXNwbjY2MjNmbWFuMGIiLCJldmVudF9pZCI6IjZiMmEyY2RkLTU3MTAtMTFlOS1hNmU1LTliYTBlYmUzYTkyMCIsInRva2VuX3VzZSI6ImlkIiwiYXV0aF90aW1lIjoxNTU0NDA2MzY0LCJuYW1lIjoiRGVuaXMgTGlnZXIiLCJjdXN0b206ZW5jcnlwdGVkRGF0YUtleSI6IkFRRURBSGprcHEzSmZTM0h3RzVcL3ZxM2JwdjhNR2NpaElnSFF5UWxCTU5jT0RrUlk4d0FBQUg0d2ZBWUpLb1pJaHZjTkFRY0dvRzh3YlFJQkFEQm9CZ2txaGtpRzl3MEJCd0V3SGdZSllJWklBV1VEQkFFdU1CRUVES081SUZocFwva3UzTjhneXpnSUJFSUE3dm1XdTlnVlg2K0IrdDIrQVppSmFcL0FXVFwvSnZPWEFWMXBGNVhXdFRzVjluaDhWa2ZEQXk5S3BZTGY3bWR0TVkxZGRhSlVyVFJ1ZDhzYTFzPSIsImV4cCI6MTU1NDg1NTQ2MiwiaWF0IjoxNTU0ODUxODYyLCJlbWFpbCI6ImxpZ2RlbmlzQGFtYXpvbi5jb20ifQ.bfFCwH6nN3mAXxwDuwyE7yZMqVwMKnOISP0jwLWZGodZ--oUepPPTvpxWskqxEqpL-Jy_rAki_g319d3opnDKaGVq0FJZjW9EneRxjPHsziUoJHysRSJrj0joCWtYGVzXB7UA6VOlO1CiqGK1i9SMG8k3i6b5EbsDWr84c_wvlVi8yy8M33oJfTLRIbFeDDYwexdT9ZDK9_rcLxnDLL3XjIqlKLj9rCsKOrEIznwZLsCfrBjQBZE8mq9VHUaajFpochyaM1rjL9J8q9-tZTcHnE1ryrLNLvW_vtS1WLic1WVTw9TkCQJCc1HT3KyI-mmqc4fg7Vyw7_RC3DcbiV7Rw
I guess you're using "Cache behavior" with "Path Pattern" to route user request to Origin? If that so, check the order of your behavior, as you list in your question, you put the * pattern in the first order, mean all request will be route to S3 which will cause 404 not found error since your S3 site doesn't have that URL path.

Redirect http:// requests to https:// on AWS API Gateway (using Custom Domains)

I'm using AWS API Gateway with a custom domain. When I try to access https://www.mydomain.com it works perfectly, but when i try http://www.mydomain.com it can't connect.
Is there a way to redirect the http -> https with the custom domain in API Gateway? If not, is there a way to get the http:// links to work just like the https:// links?
API Gateway doesn't directly support http without TLS, presumably as a security feature, as well as for some practical considerations.
There is not a particularly good way to do this for APIs in general, because redirection of a POST request from HTTP to HTTPS is actually a little bit pointless -- the data is has already been sent insecurely by the time the redirect is generated, unless the client has asked the server to inspect the request headers before the body is sent, with Expect: 100-continue.
You can create a CloudFront distribution, and configure it to redirect GET and HEAD requests from HTTP to HTTPS... but if you send a POST request to such a distribution, CloudFront doesn't redirect -- it just throws an error, since (as noted) such a redirection would be more harmful than helpful.
However... if GET is your application, then it's pretty straightforward: first, deploy your API with a Regional (not Edge-Optimized) API endpoint with a system-assigned hostname, not a custom domain.
Then, create a CloudFront distribution that uses this regional API endpoint as its origin server, and configure the CloudFront distribution's behavior to redirect HTTP to HTTPS. Associate your custom domain name with the CloudFront distribution, rather than with API Gateway directly.

How can i go to my website without typing "https://" in url. My website is hosted on aws cloudfront

I have my website like this "https://hr.mywebsite.com", I am able to go to my website when i type the whole url(https://hr.mywebsite.com).
But I want to go to my website without typing "https://".
That is if i type "hr.mywebsite.com" it should open my website. My website is hosted on AWS CloudFront.
You need to set an HTTP to HTTPS redirect on your CloudFront distribution. CloudFront has a setting for this.
To configure CloudFront to require HTTPS between viewers and CloudFront
Sign in to the AWS Management Console and open the CloudFront console at https://console.aws.amazon.com/cloudfront/.
In the top pane of the CloudFront console, choose the ID for the distribution that you want to update.
On the Behaviors tab, choose the cache behavior that you want to update, and then choose Edit.
Specify one of the following values for Viewer Protocol Policy:
Redirect HTTP to HTTPS
Viewers can use both protocols. HTTP GET and HEAD requests are automatically redirected to HTTPS requests. CloudFront returns HTTP status code 301 (Moved Permanently) along with the new HTTPS URL. The viewer then resubmits the request to CloudFront using the HTTPS URL.
Important
CloudFront doesn't redirect DELETE, OPTIONS, PATCH, POST, or PUT requests from HTTP to HTTPS. If you configure a cache behavior to redirect to HTTPS, CloudFront responds to HTTP DELETE, OPTIONS, PATCH, POST, or PUT requests for that cache behavior with HTTP status code 403 (Forbidden).
When a viewer makes an HTTP request that is redirected to an HTTPS request, CloudFront charges for both requests. For the HTTP request, the charge is only for the request and for the headers that CloudFront returns to the viewer. For the HTTPS request, the charge is for the request, and for the headers and the object that are returned by your origin.
From http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-https-viewers-to-cloudfront.html