Cross-Origin Resource Sharing: A complete tutorial
Cross-Origin resource sharing is a protocol that allows the client from one origin to interact with the resources residing on a different origin. When we say resources, it is things like API calls to fetch some data, images downloads, icons, etc. We need CORS to overwrite the same-origin-policy followed by
Browsers implement a security mechanism called same-origin policy. This policy was implemented to fight one of the most common cyber-attacks out there: cross-site request forgery. During cross-site request forgery, a malicious attacker/website tries to hijack the browser's cookie system and attempt to steal resources in the name of an authentic website.
Since the browser automatically attaches all the relevant cookies of a domain during any request, a malicious website would try to send requests to https://example.com from the browser. In such a scenario, the cookies stored in the browser for https://example.com domain will be sent. If the cookies are valid, the malicious website gains access to https://example.com and its resources. This way, a user's account will be subjected to a cross-site request forgery attack.
To prevent this, the browsers have implemented same-origin policy. This means that any requests made from the browser from a given website to the same domain will be allowed. It will stop requests coming from a different domain under
Why do browsers give CORS error? We know that the Cross-origin requests are usually blocked by the browsers due to security purposes. A webserver not only contains publicly accessible assets such as images and fonts but also contains sensitive information such as personal information of a user. These web servers sometimes provide publicly accessible APIs for other websites to consume and interact with their resources. This could be a form of service being provided by one server to another. Following are the few reasons why cross-origin requests are usually blocked by the browsers:
- The API being requested doesn't allow cross-origin resource sharing
- The API exposed allows certain qualified domains to send cross-origin resource sharing
- The API requires certain headers to be sent to allow cross-origin resource sharing
If you have involved in web development for any amount of time, I am sure you must have encountered the following error:
Every time you tried to work with external APIs, you might have faced this error. You might have also tried sending headers such as
'Access-Control-Allow-Credentials': true along with the request and could find no luck in resolving the CORS error:
Most of the time, this error can be resolved by adding certain headers like
Access-Control-Allow-Origin: "https://example.com". This essentially means that the API server hosted in a different domain trusts our domain and is willing to share its resources. The APIs are built for a common purpose, and APIs cannot start whitelisting every new domain that comes up on the internet. Also, there is no guarantee that the domain which has established the trust today won't turn malicious tomorrow.
So what to do now? Do we give up? What are the ways to resolve this issue?
There are several ways in which cors error can be resolved:
If you are only testing an API and want to use its data without dealing with the CORS issue, it is possible to install CORS plugin and make API calls from the browser as if it were requesting the resources from the same domain. Note that the plugin is only a fix in your local machine. The plugin will essentially add
Access-Control-Allow-Origin: * header to the response coming from the cross-origin server and tricks the browser into allowing the request to pass through.
The requests going from our browser can be sent through a proxy server which attaches
Access-Control-Allow-Origin: * header to every response it sends back. The cors-anywhere server acts as an intermediary proxy between the client and the server.
In this case, if you want to request to https://example.com, the request would be sent to https://cors-anywhere.herokuapp.com/, along with the information about the original server you want to hit. This solution is a great use-case when we don't want to burden ourselves with any backend programming. We will be making use of cors-anywhere and turning the (browser-server) request into (server-server) request.
One of the problems with using a third-party proxy server is the dependency. We cannot confirm its availability and its scalability. We also cannot trust it completely and send client secrets to the proxy server. A better approach is to build a proxy server and host it along with the frontend codebase. This way the requests will be first made to our server residing in the same domain, and then it will be forwarded from our server to https://example.com. This would establish a (server-server) communication and the request will be fulfilled.
CORS errors can be troublesome to front-end developers, especially when we don't have any knowledge regarding backend. In the case of simple applications, we can make use of third party proxy servers and fulfill our requests.