No ‘Access-Control-Allow-Origin’ header is present using angular + WordPress - wordpress

when i post the data using POST method in woocommerce api. i am getting cors issue
Access to fetch at 'http://localhost/wordpress/wc-api/v3/customers?oauth_consumer_key=ck_64d88e1fa3516e9f5a06b6053f02976a534d3f8f&oauth_nonce=zsu3ysEnFHhvrZt4Nc7H66Dgu28H20K7&oauth_signature_method=HMAC-SHA256&oauth_timestamp=1562587817&oauth_version=1.0&oauth_signature=KtFxvyQNklUlfCi6rNWyJ0DEJ6AS2ZbwbO44u%2FEqxG4%3D' from origin 'http://localhost:8100' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

You have to set a Access-Control-Allow-Origin header on each request to the server, if your server is on a different domain than the app on which you are making those requests (the server sets it as a response header). Adding that header tells the system that the external domain "localhost:8100" is allowed to make those requests.
You cannot circumvent this requirement in vanilla browsers, because it is a built in security feature to reduce CORS attacks
PS. different ports on the same domain are considered to be different domains. Thus example.com will get a 401 error, if you are making a request to example.com:8100. Same goes for localhost, or any other domain.
Example code from an Apache2 web server .conf file, that I personally use to set these headers.
SetEnvIf Origin "^http(s)?://(.+\.)?(staging.\xxx\.com|xxx\.com|xxx\.local|xxx\.local:4200|a2\.local)$" origin_is=$0
Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is
Just replace the xxx.com domains with localhost:8100 or whatever else you need in that array. (if you are using Apache web server)
As a result, the Chrome network tab should have an Access-Control-Allow-Origin header on attached to the request

Related

Sec-Fetch-Mode, Sec-Fetch-Dest, Sec-Fetch-Site in request header creating CORS issue

On the backend endpoint that I am requesting from my website using axios, most of the browsers do not have "sec-fetch-mode" and "sec-fetch-site" set on the request headers and they seem to work fine.
However, few browsers set the headers sec-fetch-mode:cors, sec-fetch-dest: empty and sec-fetch-site:same-site, and in that case the connection is closed and the browser console shows the following error.
Access to XMLHttpRequest at 'https://site-url.xyz/endpoint1' from origin
'https://xxx.site-url.xyz' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested resource.
The backend has the following config:
response.headers.add('Access-Control-Allow-Origin', "*")
response.headers.add('Access-Control-Allow-Headers', 'Content-Type, Authorization')
response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,OPTIONS')
response.headers.add('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')
Is there a way to control these headers from code, either from front-end or from backend?
So the issue was with Nginx configuration on the backend. It could only accept max file size of 1MB by default. So some people were able to upload docs and some were not. It's weird that I was seeing CORS issue on console.

CORS supported & dockerized web server

Given an API server with Swagger UI, I want to run this server in a docker container and access from outside world and make sure this server supports CORS.
Note that current server implementation set response header Access-Control-Allow-Origin: <request.origin> if any Origin request header exists, otherwise it is Access-Control-Allow-Origin: *.
So, I dockerized this server and it is running on default docker interface, 0.0.0.0. On localhost or any other deployment environment, api is fine through cURL, postman etc. don't make any trouble.
When I access this dockerized server from a browser to use Swagger UI, I see errors indicating OPTIONS request wasn't successful. Unlike CLI tools, browsers send OPTIONS request before actual one. After checking developer console, I see that I get No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin is therefore not allowed access.
I also see that Origin and Host request headers are different and I believe it leads to this error. For example, Origin is http://localhost:8080 and Host is 0.0.0.0:8080 due to docker. CORS reference's relevant part also mention this. I guess modern browsers implement CORS check per this reference.
I can get rid of this by setting Access-Control-Allow-Origin: * response header for all requests but that is only a work-around and not secure.
Appreciate any guide and help.
OK, a few things:
The Origin is what indicates to the server that it's a CORS request - if the Origin request header is not passed, it's not a cross-origin request, so you don't need to send any CORS response headers.
Sending Access-Control-Allow-Origin: <value-of-Origin-request-header> (what you say you're doing) is absolutely the correct thing to do. You could add code to only send the ACAO header if the Origin request header is one you trust, but that may be getting too complex at this point.
The value of the Host header should be immaterial - as long as you send back the value of the Origin header in the ACAO header, it should work.
If you're passing cookies with your request, you'll also need to return Access-Control-Allow-Credentials: true, otherwise any Set-Cookie response headers will not be processed by a browser.
To the main problem (I think) - supporting OTPIONS requests:
You are correct that browsers may send a CORS preflight OPTIONS request, whereas non-browsers do not. If so, you'll need to do the following:
Ensure your server supports OPTIONS requests (by default, many web servers only support GET, POST and HEAD out of the box)
Return the exact same ACAO header with the response to that OPTIONS request also
Handle the other CORS request headers that get passed with the preflight OPTIONS requests - Access-Control-Request-Method and Access-Control-Request-Headers.
That last bit can get tricky, but the simplest thing to do is to return the following response headers to the OPTIONS request:
Access-Control-Allow-Origin: <value-of-Origin-request-header>
Access-Control-Allow-Credentials: true
Access-Control-Allow-Method: <value-of-Access-Control-Request-Method-request-header>
Access-Control-Allow-Headers: <value-of-Access-Control-Request-Headers-request-header>
and return the following response headers with the main GET/POST request:
Access-Control-Allow-Origin: <value-of-Origin-request-header>
Access-Control-Allow-Credentials: true

how "Access-Control-Allow-Origin" header works

I have very basic question regarding the "Access-Control-Allow-Origin" header.
Assume that we have a website "www.siteA.com" that will be doing the CORS to another site "www.siteB.com" and the "Access-Control-Allow-Origin" on siteB is set as "www.siteC.com" only.
When user via browser access siteA and it tries accessing content from siteB, what will the response look like?
Will the request be blocked at the server level
or
will it send the entire response with "Access-Control-Allow-Origin" header set to "www.siteC.com" and will be blocked by user's browser? (i think the first is the correct one)
When user via browser access siteA and it tries accessing content from siteB, what will the response look like?
The same as any other response from the site.
Will the request be blocked at the server level
No. CORS is an instruction to the browser that it should not apply the Same Origin Policy to the request. The server can't (reliably) tell where a request came from to block it at the server level.
will it send the entire response with "Access-Control-Allow-Origin" header set to "www.siteC.com" and will be blocked by user's browser?
Yes.
will be blocked by user's browser?
Yes, because only www.siteC.com domain can access the resource according to your Access-Control-Allow-Origin header. They would send back;
Access-Control-Allow-Origin: http://www.siteC.com
You can find answers the questions about the Access-Control-Allow-Origin header via this.

If I change the domain of my site, what happens with the cookies?

We have a site where we are using cookies for tracking purposes. Now we are thinking in changing the domain of our site but we will want to still recognise User's sessions from the old domain. Is this possible?
You can't retrieve cookies that belong to other domains. As a workaround (in case you can still use the old domain); by creating an iframe inside http://newdomain.com from http://olddomain.com, you can get cookies and send to parent via postMessage.
Cookies are affected by same origin policy but you can bypass it with CORS (Cross-origin resource sharing).
CORS is a play between browser and server.
Basic idea is allow ajax request to cross domains but you can use to share cookies(security measures should be taken).
Browser send a request with Origin header.
If the server allows the request then it reply with Access-Control-Allow-Origin header with the value of origin.
If the server doesn’t reply with the header or don’t match Origin with Access-Control-Allow-Origin browser disallow the request.
But it doesn’t send cookies or something like that by default(you have to add “allow-credentials” extra header).
With CORS you can share the session between domains adding to new domain server the following headers:
Access-Control-Allow-Origin: https://original-domain.com
Access-Control-Allow-Credentials: true
More info about CORS:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
http://quickleft.com/blog/cookies-with-my-cors

CORS - why is Access-control-allow-origin header necessary?

Premise:
When an site (http://example.com) tries to make a cross-origin request, the browser will send an HTTP request to the cross-origin server (http://other-server.com) with the header Origin: http://example.com. If the server at http://other-server.com approves http://example.com as a valid origin, then it will 1) Respond without error AND 2) set the response header to Access-control-allow-origin: http://example.com
My question is - why is it necessary to set the Access-control-allow-origin header in the response? Doesn't responding without error already acknowledge that the server (http://other-server.com) is allowing the cross-origin request?
This extra layer of acknowledgement gives servers a lot of flexibility over how they support CORS. For example:
1) A server has a lot of choices when setting the Access-Control-Allow-Origin header. It can use the * value to allow all clients, or it can limit the scope of clients by using the actual value of the origin (e.g. http://example.com). If a server does support CORS, but not for all origins, it could respond without error, but the Access-Control-Allow-Origin could be set to http://notyourorigin.com.
2) CORS allows even more flexibility via the Access-Control-Allow-Methods and Access-Control-Allow-Headers preflight response headers. These headers go beyond the simple binary success/error HTTP status, and provide more nuanced information about what is and is not supported in the server.
As the examples above point out, an error response without any context can be very confusing to the user. If you make a CORS request, and all you get back is an error response, you have no idea why that request failed. Are you doing the request wrong? Does the server support CORS at all? This can be very difficult to figure out without any accompanying information. The Access-Control-* gives more context to the user so they can effectively debug their CORS requests.

Resources