Check out a free preview of the full API Design in Node.js (using Express & Mongo) course:
The "Understanding CORS" Lesson is part of the full, API Design in Node.js (using Express & Mongo) course featured in this preview video. Here's what you'd learn in this lesson:

Scott installs the blog user interface which will be used throughout the rest of the course for working with the API. Since the blog interface runs on a separate port, CORS will need to be enabled to allow access to resources form different origins.

Get Unlimited Access Now

Transcript from the "Understanding CORS" Lesson

[00:00:00]
>> [MUSIC]

[00:00:03]
>> Scott Moss: Okay, so there's a couple things we need to talk about before we work on this. The first thing let's get that other repo up and running cuz that might take a minute. So, if everybody, alrighty, I recommend you do this. I mean, I guess you don't really have to, you can test the API from whatever tool you've been testing.

[00:00:20] But, if you just want to have an app that actually shows the data stuff. I think it'd be really cool. If you go to GitHub and fork or clone this repo, angular dash components.
>> Scott Moss: I'll give everybody a little bit to get that URL and then we'll go forward.

[00:00:45]
>> Mark: They're asking, can you just send the user when you first send the JSON web token and store it in local storage?
>> Scott Moss: Yeah, you could totally send a user on their first time. There's nothing wrong with that. If you want to, yeah, you could send the user, but what if that user object gets updated, and now you have still data.

[00:01:04] Having a still token is okay, there's really no such thing, as long as it doesn't expire. There's use cases for both. Sometimes you might wanna do that. I can see that happening in a mobile application, or maybe if you had offline capability that'd be really great. In blogging you probably do have offline capabilities.

[00:01:22] So, it all depends on you. How important is it that your data is always up to date?
>> Mark: And little while back, somebody was bringing up about pre hooks.
>> Scott Moss: Mm-hm.
>> Mark: He wasn't sure if you had mentioned pre hooks in Mongoose only work on save and not on update.

[00:01:42]
>> Scott Moss: Yeah, I mentioned that. They only work on save, never on update.
>> Mark: Okay, you wanna just elaborate on that?
>> Scott Moss: I think it is as simple as it's sounds. They did that for a reason. They don't want, there's things, you have weird side effects like for instance if you go look at our user model and on safe it's like all right before saving encrypt a password.

[00:02:05] So let's say I create a user before it got saved, it encrypted the password, great. I got the same user like a day later, and I updated its user name. Now it's gonna come back here and encrypt the password again. The password never was changed. So, that's what this check is for, the check is like if the password's not modified that's great.

[00:02:24] But the whole point of save is just, this is a one time thing, only I wanna change it when it's first created. And this is I think it was designed by choice. I'm not sure the exact reason behind it but for me, it kinda make sense because on update you might have unexpected side effects.

[00:02:42] Because you're change in different properties on that update, whereas this is, here's a new instance created. It's almost you're subscribing to the collection, and not subscribing to changes on the model itself. So the pre-save is, if anything changes in this collection, let me know. And not if anything changes on this model, which I think is what that person is thinking of.

[00:03:05] So it's not presave on the actual instance. It's listing for stuff on the collection when the instance is saved.
>> Scott Moss: Cuz, so yeah before I could clone this, this will probably helpful. And then to get started with that one so if you're on that one, first thing you should do is empty uninstall and keep a habit doing that.

[00:03:35] There's a lot of stuff on this one because this was built using years 2015 and angular webpack and code all types of crazy stuff. Yeah.
>> Scott Moss: Cool. So once you implement style, you can just type in npn start and you'll see some output here. Don't worry about any of that stuff.

[00:03:59] And keep waiting for it. It's building, it's building all the files. And then boom, it spits this stuff out. So if you just go to port 4500, you'll see the app.
>> Student 1: What is npm start?
>> Scott Moss: What does NPM start do? Good question. So I think we have on our API as well.

[00:04:18] Yeah, so if you go look at the package.json, there's a field that says scripts and it's a shortcut, so if I type in mpm start, run as command. Mpm test. Run as command. Yep. It's just a way of abstracting away your build systems so people don't have to know.

[00:04:31] They don't really care what tool you use. They just type in mpm start and it should start the thing. If you're using go or broccoli or web pack or noteline, or whatever, if you type in mpm start, it should work.
>> Scott Moss: So, in the case of that app that we just downloaded, its using gulp and webpack.

[00:04:49] So npm and start calls gulp. Yup, Mark?
>> Mark: Asking about if using objectId for your user ID. Are there security concerns sending back the mondodb objectId in plain text?
>> Scott Moss: Are there security concerns of, first of all where am I doing that, let me see. I'm not sure exactly where I'm sending back that, you mean on all the requests.

[00:05:13] Well I mean, it is as much of a concern or least of a concern as sending back ID. On a SQL database. So, if you have you're sending back the IDs. I think for most applications, you need the IDs of things. That's how we sub relationships on a client.

[00:05:29] So, if it is a security concern, then every single other database that sends back IDs is a security concern. It's not unique to Mongo. But we definitely need the IDs to identify things instead of relationships.
>> Scott Moss: Passwords, though, probably not. They'll only send that stuff, and by default, we are sending back the hash passwords.

[00:05:49] If you've looked, if you've gotten stepped up and looked, you see that we're sending back the hash passwords. So, we'll have to get around that. Where was I? Yeah. So here, if you go to local host 4500, you should see the blog. And if you start it up and if you were curious and you looked in the console and actually if you click on blog and then you look on the console, you'll see that it actually went in and got all the blog posts on my server.

[00:06:18] This is the mock data that I wrote, or the mock data in your C database. It pulled it up, and it got it.
>> Scott Moss: Everybody see that? So you have the data there, and you click on it, it will just show you the bar.
>> Student 2: Quick question, going back to the last one.

[00:06:39] So, let's just say you do have something that's more sensitive, like orders and say that your id's have Sequential versus these Mongo IDs which are a little more GUI like. I presume there is somewhere in middleware or somewhere where you'd say, hey, if you are trying to get order two, and your not really part of order two, you shouldn't get that.

[00:07:00] There's some logic you have to build in.
>> Scott Moss: Yeah.
>> Student 2: Kind of lock that down.
>> Scott Moss: Yeah, I think I told you that. That's more, yeah you could do that. I mean there's a lot of ways you could do that, you could set up sub documents, or you could set up harder restrictions or do some pre-hooks on this type of stuff.

[00:07:17] Hold on, let me check before I do this. Yeah, you could totally do that.
>> Scott Moss: Cool, so again, this blog is getting the data from localhost 3000 which is our server. Right, so if I go look at the server, you'll see that there it is. It went and got it.

[00:07:32]
>> Student 2: [COUGH]
>> Scott Moss: If I refresh the page, you'll see that it will get it again. Yeah, it got it again, 304.
>> Scott Moss: So in order for that to work, there's something that we need to understand. And I'm just gonna go over it briefly cuz I think people may know about it.

[00:07:52] Or, I'm sure a lot of people know about it, who am I kidding? So in middleware, app.middleware, we added two more middleware. One is unimportant, but one is very important, and that's CORS. All right, does anybody not know what CORS is? You don't know what CORS is? So, CORS is Cross-Origin Resource Sharing.

[00:08:11] So by default, if I'm on local host 4500. And I am trying to access a route on localhost 3000. The browsers aren't gonna let me. They are gonna, no you can't do it. It's a security concern, all right. So, ways around that include things like JSON P which is still pretty widely used.

[00:08:33] Or you just have your server enable CORS. And what that does is, so in Chrome, when Chrome makes a request to your server, it actually makes two requests, for one request. It does what's called like a preflight check. A preflight check is just, there's another verb other than, let me see.

[00:08:56] There's another verb other than get posts put and delete, there's another one called options. And an options request, is what the browser was sent to the server. It's, hey, am I allowed to make a request to you? And the server can say yes or no. So, it responds backward 200.

[00:09:09] It's, yeah, you're okay. Which is, of course, enabled. Right, so now, you can share these resources across different domains, different origins. Or it can be, hold up, let me check your domain to see if you, let me see if you're on the white list. Or let me see if you have this.

[00:09:22] So you can do different things. And they're, no, no, you're not allowed. And then Chrome will come back to them, nope, you're just weren't allowed. So, to show you what that means. If I get rid of this right here. So I got rid of that. And then, did the server restart?

[00:09:39] Yeah. If I refresh, there it is. So, Chrome threw an error. It says cannot load, no Access-Control-Allow-Origin header is present on the requested resource. Origin 4500 is therefore not allowed access. It's because we didn't enable CORS. Enabling CORS is really just accepting that pre-flight check, and setting up the appropriate headers, which include this header that Chrome is freaking out about.

[00:10:03] So, it's, you didn't say that Access-Control-Allow-Origin. So, this is a middleware that I downloaded, MPM Install Cors, and it just does that for you. We can do this ourselves, too. It's really simple. But, it's a thing that does it for us, so enabling that. I now am able to share resources across different origins.

[00:10:22] Now I refresh it's, yeah, they're fine.
>> Student 3: And does that allow any origin then?
>> Scott Moss: By default, yeah, any origin. But the CORS middleware takes options. It will take a white list array like only white listies or black listies, or whatever. Yeah. So we have CORS, are there any questions on CORSes, of course?

[00:10:45] That's very important, the reason they're built into APIs is other people are gonna consume, there should probably be CORS enabled.
>> Student 4: Computer identity [INAUDIBLE] your server, normally you're doing [INAUDIBLE] computer there?
>> Scott Moss: Yeah, so if you have a proxy Engine X on it then you would deal with it there, which is a good idea, yes.

[00:11:04]
>> Scott Moss: Engine X is awesome.
>> Scott Moss: Okay, so we've got CORS in. I guess it's worth mentioning the other one, this method override one. This is just, well actually I don't know exactly what this one does. If anybody knows exactly what this one does let me I just know that if I always use it.

[00:11:19] So, some would do would like to put in the patch or something like that. Not too sure. But I'll put it there.