We don't talk about web application security much at Epicodus because it's beyond the scope of what we teach. However, there is one important topic we need to cover briefly now that we are working with API calls.
Browsers use same-origin policy (SOP) to prevent cross scripting attacks. A cross scripting attack is when a malicious user attempts to access another site via the browser. This generally involves injecting malicious scripts into a web application in an attempt to gain access, get data, or sabotage a site.
Same-origin policy means that a request can only be made from one URL to another if the receiver and the sender have the same protocol, host, and port.
Here's a quick example:
In the URL above,
https is the protocol and
thisisthehost.com is the host. There is no port, and generally there won't be when we are navigating between pages, but a port would look something like this
:80 and would come right after the host. We do often use ports with development servers so they can potentially be relevant in development.
Let's say that the following URL wants to make a request of the URL above:
That would be entirely fine. The protocol and host are the same. The only thing different is the path, which is
someotherpage instead of
How about the following URL?
Well, the host name should give it away, but this is a different origin for two reasons. There's a different protocol (http instead of https) and there's a different host:
somebodysuspicious.com. Because of SOP, a browser will not allow this URL to make a request to
https://thisisthehost.com/somepage. Nor would the browser allow a request from `
http://thisisthehost.com/someotherpage - even though the host name is the same, the protocol is different.
So why is this important when it comes to making API calls?
Well, our applicatons are entirely client-side. All the code we are running is running from the browser. We are requesting data in the form of JSON, not HTTP, but we are still doing so via a client. That means that SOP applies to our applications.
But wait a minute... how have we been able to make API calls to the OpenWeatherAPI then? How about other APIs we are working with like Giphy?
Well, these APIs have enabled a feature called cross-origin resource sharing or CORS for short. The name is pretty self-explanatory. It's a mechanism that allows resources to be shared across different origins.
It's not really necessary to know the ins and outs of how cross-origin resource sharing works, but on the most basic level, it means attaching a few extra headers to requests and responses. That all happens behind the scenes so we don't need to worry about it.
What matters for us is that the APIs we work with must have CORS enabled if we want to work with them. If an API doesn't have CORS, we can't make API calls from a browser application.
For that reason, if you want to build a client-side application that makes API calls, you need to do some research first and make sure that CORS is allowed. It's not enough to make sure an API call works from Postman. In fact, that doesn't tell us anything about whether it works from the browser! Postman isn't making calls from the browser so the rules of SOP don't apply.
If you try to make a request from the browser to an API call that doesn't allow CORS, you'll get the following error in the console:
Access to fetch at 'https://othersite.com' from origin 'https://mysite.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Note that the names of the sites will be different depending on the URL you are trying to access and the one you are working with.
Let's say you really want to work with an API that doesn't allow CORS. Is there any way around this restriction? Well, there are several options:
So while you are welcome to use one of these extensions, just keep that fact in mind. We are still early in the program so you may not plan to turn learning projects into portfolio projects. That being said, we still recommend you pick APIs that allow CORS.
Lesson 19 of 26
Last updated October 12, 2021