Lesson Summary: CORS (Cross-Origin Resource Sharing)
Overview
In this lesson, we further explored the concept of CORS (Cross-Origin Resource Sharing) and the issue we encountered when attempting to fetch resources from a backend server.
Key Topics
CORS Definition:
CORS allows web applications running at one origin to access resources from a different origin through additional HTTP headers.
Problem Encountered:
Previously, a fetch request failed due to the absence of the Access-Control-Allow-Origin header, causing the server to block the request.
Middleware:
We discussed how middleware functions as an intermediary that processes requests before they reach the route handlers.
Reproducing the Error:
The error was reproduced by commenting out the CORS middleware, leading to a request showing a status of "fail" and an origin of "null" when running locally.
Access-Control-Allow-Origin Header:
This header is necessary for the server to allow requests from different origins. The * value indicates that requests from any origin are allowed.
Understanding Same-Origin Policy:
Browsers enforce the same-origin policy by default, which restricts how documents or scripts from one origin interact with resources from another.
Setting Up a Custom Middleware:
We created a simple middleware to set the Access-Control-Allow-Origin header in the response. This included:
Defining an anonymous function with parameters req, res, and next.
Using res.set to define the Access-Control-Allow-Origin header.
Calling next() to pass control to the next middleware or route handler.
Testing the Custom Middleware:
After implementing the custom middleware, we tested the server again to ensure the response headers included the correct CORS headers, confirming that the fetch request would now succeed.
Conclusion
By understanding and implementing CORS, we learned how to enable cross-origin requests, which are blocked by default due to security policies in modern web browsers. We also gained hands-on experience in creating middleware to manage HTTP headers for CORS compliance.
This completes the lesson, and further exploration can be done on specific configurations and security practices when using CORS in real applications.
Video Transcript
Welcome to another lesson.
In this lesson, I would like to talk more about what course means.
In the previous lesson, we had a problem where when we did fetch, it would not fetch the
resource from our back-end server due to some policy, due to something called CORS
course.
Course means cross-origin resource sharing.
Now the problem that we had had to do with some HTTP header called access-control-allow-origin.
Now what do they all really mean?
In the previous lesson, I taught you how to get around a problem by installing a third-party
NPM package called CORS course.
Then we use that package as a middleware to our server.
A middleware is something that stays in between when the client requests something.
Your server is listening and takes that and directs that request to the appropriate route
handler.
Now in between that, we can put a middleware so every time the client requests for something
on the server, it will pass first through the middleware and only after having passed
through the middleware will it end up in the route handler.
Now let's dive into what CORS really means.
Let's reproduce the error again.
This lesson will be dedicated into going into more details about this problem.
So let's go here.
Back to server.js, we have the endpoint slash entries.
Now we have this app.useCORS.
We're using the CORS middleware.
I am going to comment this out, meaning it will no longer be executed.
A slash slash preceding at the beginning slash slash everything after the slash slash
the double slash will be commented out.
That is, the code will not be seen, but will not be run.
With that, we'll have the problem again.
Let's reproduce it.
Let me run the server because I had it shut down.
I'm going to say node server.js.
Now server is listening on port 3000.
Let's go back to our application in the browser.
So here I have, I'm going to refresh.
And before I do that, I want to click the network tab of the browser developer tools.
Now you can filter these by XHR, JS, CSS, and so on.
And you can see all is marked right now.
That means all the requests appear here in this convenient table.
We're interested in the request of type fetch.
That's fetching the entries, right?
If you hover over the row, whose name is entries, you're going to see it's a request to local
host on the port 3000 slash entries in the status.
The last time I run this was 200 real cake.
Now if you want to, I just want to teach you about these filters.
What we do with fetch is what's called next HR request.
Okay, it's a HTML HTTP request.
That's what that means.
So that's what we want.
Every time you use fetch to grab something from the server, you're going to be making
an XHR call XML HTTP request.
So I'm going to filter right that.
And you're going to see XHR and fetch.
It's the only one that appears.
I'm going to click on that and I can see the headers response from the response.
And I can see the headers from the request.
Now I can see the preview under the preview tab is the response where I know that.
Great.
Now I'm going to refresh and watch the request there.
Now the request turned red.
Now if you can see here the color changed to red because there was a problem.
You can see the status column now says fail.
Let's click the row and then let's see.
There's nothing here that tells us what went wrong.
But how about we go back here to the console tab and you can see that error again.
We had that before.
Now let's dive deeper into this.
What does this really mean?
Let's read it again.
So access to fetch at HTTP colon slash slash local host colon 3000.
That's the port slash entries the endpoint.
From origin no.
Now notice no origin is no.
So it's telling us that the origin from this request is no.
And that just means that I'm running it from my local file system.
That's the origin.
Now this request has been blocked by a course policy.
Course C O R S.
Right cross origin resource sharing.
Notice cross origin.
We're going to remember that for later on cross origin.
No access control allow origin access dash control dash allow dash origin header.
It's an HTTP header is present on the requested resource.
So it's telling us that this specific header was not present.
So the server.
Right.
Receive the with where the client we asked for the entries.
The server sent back something but the header was not set.
Now if an opaque response serves your needs set the request mode to no course.
Refatch the resource of course disabled.
It's telling us we can get around it by setting no course.
It will not use that policy.
But we're not we're not going to go that route.
So that's why it failed.
Now if you go back to the network tab and you click the entries row check out the headers
tab and you can see here you have request headers response header etc.
Now if we go back to the text editor and add back on comment the line with app.use
C O R S course and restart the server.
Let me kill control C and then I'm going to rerun node server.js.
Let's see it's going to succeed now right.
But keep it keep in mind what you see on the response headers or request headers.
Now click the entries again and you can see for the response headers.
Okay.
Response headers those are the headers sent by the server right because you have the request
and you have the response the client makes the request to the server the server and churn
sends a response and that response also includes headers.
They are HTTP headers.
Right now look at that there is a header here entry called access dash control dash allow
dash origin and its value is star.
Now this header from the response was set by the middleware course right the third party
npm module and its value is star.
Star means you can think of star as everything meaning allow any origin.
Okay.
Nice.
Now we got that.
Now let's dive into a little bit of theory like what is course now that we saw some things
here in practice let's dive into more of an overview.
So I'm going to go to my browser and I'm going to go to the npmmdn website developer.mozoo.org
now we're going to do a search here.
With the search bar let's type cross origin resource sharing and I have my the first entry
this is the page I want to read so let's read this.
Cross origin resource sharing.
Cross origin resource sharing is a mechanism that uses additional HTTP headers to tell
browsers to give a web application running at one origin access to selected resources
from a different origin.
Now you can see a different origin that's key so the cross origin means different origin
so you're going to have for example you have the client he's in some location a the client
makes a request to some location B. Now because the request that was made is is from a client
that is somewhere else right the server is in a different place so we have a cross origin
it's not the same origin it's a cross origin different origin because of that because of
the course policy the header that was not present it will not allow this because by
default it only allows same origin we're going to read it right now.
So let's read here continue reading.
Web application executes cross origin HTTP request when it requests a resource that has
a different origin domain protocol or port from its own.
An example of a cross origin request the front end JavaScript code that's that's our
write something app served from HTTPS colon slash slash domain a dot com uses XML HTTP
request this is XHR that's exactly what we did with fetch right to make a request for
HTTPS colon slash slash domain B domain B dot com slash data.json so domain B in this case
would be our server right well keep in mind even though they're in the same kind of computer
my local computer they're actually have different domains because I'm running the write something
in a local in a local file here in the browser and the service being run on port 3000 and
the domain there would be the local host while the domain for this app here running directly
through the browser with the file system page would be actually a no domain as evidenced
from the error we got here in the console remember we had the error no for the origin
anyway let's continue so for scary reasons third paragraph browsers restrict cross origin
HTTP requests initiated from scripts so it's restricted cross origin for example XML HTTP
request and the fetch API follow the same origin policy this is key that's why our our fetch did
not work because it follows by default the same origin policy meaning if you request something that
something must come from the same origin if it does not come from the same origin I'm not gonna
allow it you're not gonna be allowed to fulfill that request successfully this means the web
application using those APIs and only request resources from the same origin the applications
loaded from less responsible in other origins includes the right course headers the right
course headers now this is telling us we need to set the right course headers and that would be
the in this case in our case would be that header that we saw in the error description I open to my
text editor that would be the access control our origin header that's what we want to set right
remember it was set to star meaning any origin is allowed here's a nice diagram you can take a look
at this you have the domain a request something from the same origin domain a.com domain a.com
that's fine same origin policy now if you have something else in your web page that request
from another server right another place that's domain B that's not the same origin then then it
will not be allowed by default through the same origin policy so we need to find a way to allow
this to happen and the way is through adding that header right the course header to tell it okay
it's fine you can make the request and the origin can be whatever RG specify or in this very general
case that we're doing it could be any origin mind you that usually you want to set very specific
origins for your resource batch right operations because you don't want to allow just about anyone
right usually want to constrain all your new client can only make you make a request of some
servers different servers all different servers all these different servers are known to you so you
take those origins and you what you make up a list of allowed origins right and that's what you
usually put in the header that we're going to change but since we're doing just for educational
purposes here I'm just going to use star to mean any header okay star to any header you can read on
here if you want to know more about course I recommend a highly recommended MD and web docs if
you want to know more about it that's click same origin policy and follow up is something more
interesting here and you can read more about this one all kinds of stuff are interested in the header
actually is this the page that I want to know maybe I was in the wrong page I'm gonna go back
I am interested in the header that I saw something interesting before here
let me see if I can find it or source origin PPI let's go back same origin sorry I wanted to
see something here if they had the headers anyway I didn't find anything here but you can read
through if you want to know more about this in case we got a overview of course and now let's do more
practice what I want to know is kind of let us make a middleware like the course middleware to set
the header so everything works fine and this is in a way replicating the behavior the most
essential behavior of that course npm package although I was I would say it's not really everything
is just one thing we're gonna do so let's go back to the text editor go to server.js now let's
come coming out app.use course again I'm not gonna use it we're gonna get an error right okay let's
make our own middleware to make our own middleware simple just say app.use and now you're gonna pass
something that's gonna be the middleware before we had the course middleware that was already
set right but it was already written by somebody else and we just downloaded that npm package into
our application now let's make our own I'm gonna make an anonymous function here first argument is
rec second arguments resin the third argument important is next now put the arrow there open
the braces so this is an anonymous function the arrow function these are the parameters 3 first
being the request second the response third the next this next would be very important the
arrow and the braces and the body of the function let's go so what I'm gonna do here is I want to
find a way that when we send the response here line 28 for all the entries I want to send out
response with the HTTP header set that will make the course thing work fine and I'm gonna do the
following I'm gonna set response write res res dot set this method or function is used to set an
HTTP header for the response first argument is the name of the header second argument is the value
okay so I'm use double quotes here I'm gonna use that header let me grab the name again access
control allow origin right let me copy this paste this is the name of the header access dash
control dash allow dash origin and comma the value would be what will the value be well we can use
start to allow any origin or you can use your domain a whatever domain be whatever I don't know if
it's comma separated it's probably is I don't know what have to reference documentation anyway
let's let's try something really simple I want to know what the error message says again go back
to the browser let me see if I can restart my server back to the browser you click network tab
what happened here oh no it's hanging on the middle adder because I did not do something that's
something's calling next so it's hanging on the request because it's stuck in the middleware
and it doesn't know what to do just stuck there so you have to tell okay I did everything in the
middleware that I wanted to do now you can go on and go to the endpoint route handlers and to do
that you call next here after you do everything you want in the middleware make sure you always call
next so that the handling of this request is passed on to the next thing in this case thing
could be another middleware but ultimately it would end up in the route handler right the endpoint
in this case with these slash entries will end up here so let me have ads and I forgot restart my
server now we got a problem because this now I wanted to know it's from origin no now what would
happen if I added no to that value of the header let's check it out go back here I'm gonna uncomment
this and I'm gonna say no for the access control our origin so I'm allowing no the origin no
restart the server oh amazing it worked right so let's take a look at the network tab like the
entries rule up under hairs response header now includes the header access control our origin
whose value is no now because no no is origin here it worked okay so that's how you handle the
this problem with a mirrorware now we've seen in a way what happens behind the scenes of course of
course this is a very very simple part of that I'm sure if you want you could look into the
source code for that just go to the npm package page and see if you can take a look at that or
it's even here actually this package is installed under the node modules and cores and here's the
source code you can look at think it's live index and you can see everything when you call cores
this is what happens all this stuff and of course our version is a lot more simpler than
all everything that's happening here but you can see if you look for that allow I forget I always
forget the header name a lot origin let me remove this you see you can see here access control
our origin headers push seems like it's setting the header some way and the value star remember
saw star before and that means any origin right so it's saying if there is no origin
defining the options which we did not define because we just passed an empty that's no argument to
the course function code right or the options are just star just push the access control our
origin star that's what we saw before in the network that when we use the course and that's
essentially what it's doing right now this stuff all this stuff all this stuff all this stuff and
you can see there's rack res and next here too it's a lot more complicated any case you want to take a
look that just for fun it's there under node modules slash core slash live setting slash index dot j
s I'm going to close this and let's go back to what we were doing here semicolon just for style
so let's summarize and what we did let's go over what we did in this lesson in this lesson we
talked more about cores cross origin resource sharing we learned about this HTTP header access
control our origin access dash control dash allow dash origin and this is how we get around that
problem where fetch failed and this is because of security that's built into the browsing how it
deals with request and response to another server it's all about cross origin meaning if the client
request something that's on a different origin right by default fetch would not allow that due to
its same no same origin policy how to get around that too thanks to that problem right we have to set
the header on the server side we used a middleware before called course but here we set our own to
learn how to make a mirror where you're simply you can set and use app.use pass it an anonymous
function of three parameters rack res and next very important that after doing what you want to do
in the middleware that you call next otherwise the request will be stuck there and your client will
be seeing a pending request that will never get a response so important to call next so it will
proceed and pass and go on on the chain of request response in this case if there were
auto middlewares those middlewares would be called otherwise ultimately it always ends up in the
route handler here line 14 in this case in our middleware we use res the response object
dot set this method can be used to set an HTTP header the first argument being the name of the
header the second the value and we set it to no I use no because the way we wrote the app locally
and everything no is the origin when you run the file the HTML file directly from the file system
although this is not really recommended okay usually want to specify exactly which
origin is he wants to allow or for the purposes of our educational and educational learning I'm
going to use the star to mean any origin is allowed that means that your client and in this case
it could be any origin right any cross origin request is fine
okay
okay and if you want to keep this or you can go back to using course it's up to you
maybe I'll keep both or not maybe I'll just delete this and just let it use course and use the
default with the star okay and then I'm going to go here back in the terminal restart my server
and see how everything is working fine below the page is fine interest appeared and you see the
header response has allowed control allow or access control allowed origin for the star meaning any
origin great so for this lesson that's it for this lesson and I'll see you on the next one