Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:01,210 --> 00:00:03,330
In this lecture we're gonna implement something
2
00:00:03,330 --> 00:00:08,020
called CORS, which means cross-origin resource sharing.
3
00:00:08,020 --> 00:00:11,670
And this is a fundamental feature in any API,
4
00:00:11,670 --> 00:00:13,400
but I can only show you this now
5
00:00:13,400 --> 00:00:16,183
that the application is actually already deployed.
6
00:00:17,900 --> 00:00:21,610
Now what actually is cross-origin resource sharing,
7
00:00:21,610 --> 00:00:24,170
and why do we need to implement it?
8
00:00:24,170 --> 00:00:26,610
Well let's say we have our API
9
00:00:26,610 --> 00:00:31,610
here at natours-jonas.herokuapp.com/api/v1,
10
00:00:34,570 --> 00:00:36,180
and so on and so forth.
11
00:00:36,180 --> 00:00:40,393
And then some other website, for example at example.com,
12
00:00:41,860 --> 00:00:44,380
is trying to access our API.
13
00:00:44,380 --> 00:00:48,470
So basically trying to call this URL here.
14
00:00:48,470 --> 00:00:51,730
And this is then called a cross-origin request,
15
00:00:51,730 --> 00:00:54,940
because herokuapp.com is a different domain
16
00:00:54,940 --> 00:00:58,550
than example.com, and so therefore if example.com
17
00:00:58,550 --> 00:01:01,570
is trying to access herokuapp.com,
18
00:01:01,570 --> 00:01:05,519
it will be a cross-origin request, all right?
19
00:01:05,519 --> 00:01:09,160
Now usually cross-origin requests are not allowed,
20
00:01:09,160 --> 00:01:13,290
and will by default fail, unless we implement CORS,
21
00:01:13,290 --> 00:01:16,660
so cross-origin resource sharing.
22
00:01:16,660 --> 00:01:20,660
And since we want to make our API available to everyone,
23
00:01:20,660 --> 00:01:25,240
we definitely need to implement that, all right?
24
00:01:25,240 --> 00:01:27,933
Now let me actually show you how this would fail.
25
00:01:28,800 --> 00:01:31,073
So let's grab this URL here,
26
00:01:31,920 --> 00:01:35,743
and open in your tab and then inspect.
27
00:01:36,770 --> 00:01:41,320
And so basically let's do an HTTP request to our API
28
00:01:41,320 --> 00:01:43,540
here from the console, okay?
29
00:01:43,540 --> 00:01:45,840
Because basically when we do it from here,
30
00:01:45,840 --> 00:01:48,273
it will also be a cross-origin request.
31
00:01:49,260 --> 00:01:53,440
So let's just say const x equals await,
32
00:01:53,440 --> 00:01:58,100
and then let's use the fetch JavaScript function, all right?
33
00:01:58,100 --> 00:02:00,050
So fetch is basically a function
34
00:02:00,050 --> 00:02:02,600
that's a bit similar to the Axios library
35
00:02:02,600 --> 00:02:04,640
that we used in our code,
36
00:02:04,640 --> 00:02:07,080
but it's native JavaScript in the browser,
37
00:02:07,080 --> 00:02:10,100
and so we can just use it here in the console.
38
00:02:10,100 --> 00:02:12,900
So let's say that we want to do a request
39
00:02:12,900 --> 00:02:17,460
to our tours API like this, all right?
40
00:02:17,460 --> 00:02:20,870
So if we try this now, let's see what we get.
41
00:02:20,870 --> 00:02:22,480
And indeed we get the error
42
00:02:22,480 --> 00:02:24,990
that trying to access this path here
43
00:02:24,990 --> 00:02:29,900
from this other origin has been blocked by the CORS policy.
44
00:02:29,900 --> 00:02:32,350
And so that is exactly what I said before.
45
00:02:32,350 --> 00:02:35,320
So that by default, a cross-origin request
46
00:02:35,320 --> 00:02:37,250
will always be blocked.
47
00:02:37,250 --> 00:02:40,270
Now by the way, this only applies to requests
48
00:02:40,270 --> 00:02:41,880
made from the browser.
49
00:02:41,880 --> 00:02:44,990
For example, using the fetch API here,
50
00:02:44,990 --> 00:02:47,260
or something like the Axios library
51
00:02:47,260 --> 00:02:49,010
that we used in our code.
52
00:02:49,010 --> 00:02:51,210
And so that means that from the server,
53
00:02:51,210 --> 00:02:54,500
we will always be able to make cross-origin requests
54
00:02:54,500 --> 00:02:55,920
without any problems.
55
00:02:55,920 --> 00:02:58,620
So there are no restrictions on the server,
56
00:02:58,620 --> 00:03:00,500
but really only on the browser,
57
00:03:00,500 --> 00:03:03,080
for security reasons basically.
58
00:03:03,080 --> 00:03:06,680
Oh, and also in order to be considered cross-origin,
59
00:03:06,680 --> 00:03:09,440
a request might come from a different domain.
60
00:03:09,440 --> 00:03:12,020
So just as we saw in our first example here,
61
00:03:12,020 --> 00:03:15,160
but also a different subdomain, a different protocol,
62
00:03:15,160 --> 00:03:17,650
or even a different port is considered
63
00:03:17,650 --> 00:03:19,950
a cross-origin request.
64
00:03:19,950 --> 00:03:24,950
So for example, if we had API.natours.com for our API,
65
00:03:27,100 --> 00:03:31,480
and would then do a request from natours.com,
66
00:03:31,480 --> 00:03:34,650
that would then also be considered a cross-origin request,
67
00:03:34,650 --> 00:03:37,200
and would fail, okay?
68
00:03:37,200 --> 00:03:39,950
But again, since we want to allow other websites
69
00:03:39,950 --> 00:03:42,410
to basically access our API,
70
00:03:42,410 --> 00:03:45,423
let's now implement cross-origin resource sharing.
71
00:03:46,680 --> 00:03:49,620
All right, and so we do that once more
72
00:03:49,620 --> 00:03:51,653
by installing an NPM package.
73
00:03:53,130 --> 00:03:55,940
So NPM install, and simply CORS.
74
00:03:57,770 --> 00:03:59,933
Then here we require that package.
75
00:04:08,140 --> 00:04:10,450
And once again, this CORS here
76
00:04:10,450 --> 00:04:12,480
is a very simple middleware function
77
00:04:12,480 --> 00:04:17,480
that we now need to use for our application, all right?
78
00:04:17,579 --> 00:04:20,250
So let's do that here, and why not do it
79
00:04:20,250 --> 00:04:21,533
right here at the top?
80
00:04:22,980 --> 00:04:25,930
So let's say implement CORS.
81
00:04:28,240 --> 00:04:32,380
And so app.use, and then call CORS,
82
00:04:32,380 --> 00:04:35,270
which in turn will return a middleware function
83
00:04:35,270 --> 00:04:37,860
which is then gonna add a couple of different headers
84
00:04:37,860 --> 00:04:39,580
to our response.
85
00:04:39,580 --> 00:04:41,870
And since all this middleware function here does
86
00:04:41,870 --> 00:04:44,820
is to basically add some specific headers,
87
00:04:44,820 --> 00:04:46,767
maybe you're thinking "Why we are using
88
00:04:46,767 --> 00:04:49,060
"yet another NPM package?"
89
00:04:49,060 --> 00:04:51,240
Well, let's just actually take a look
90
00:04:51,240 --> 00:04:52,853
at the code of this package.
91
00:04:55,370 --> 00:04:58,820
So GitHub CORS, so once more,
92
00:04:58,820 --> 00:05:02,490
that's usually how I find documentation
93
00:05:02,490 --> 00:05:05,610
or the source code itself for my packages.
94
00:05:05,610 --> 00:05:08,730
And so let's go here into lib,
95
00:05:08,730 --> 00:05:10,793
which usually means library.
96
00:05:11,870 --> 00:05:15,960
And then all we really have here is this index.js.
97
00:05:15,960 --> 00:05:20,020
And so you see that here is all the code,
98
00:05:20,020 --> 00:05:21,500
and basically what you see here
99
00:05:21,500 --> 00:05:24,730
is that it simply adds this header here
100
00:05:24,730 --> 00:05:28,653
with the value of basically everything to the headers.
101
00:05:29,850 --> 00:05:33,740
All right, so then you have a couple of other headers,
102
00:05:33,740 --> 00:05:37,320
Access-Control-Allow-Methods, allow-credentials,
103
00:05:37,320 --> 00:05:40,003
and that's for different cases.
104
00:05:40,900 --> 00:05:42,800
All right, but so you see that it's really
105
00:05:42,800 --> 00:05:45,010
just all about headers here.
106
00:05:45,010 --> 00:05:49,000
So yeah, maybe we could just add these headers by ourselves,
107
00:05:49,000 --> 00:05:51,430
but why would we actually do that?
108
00:05:51,430 --> 00:05:52,810
I mean we could of course,
109
00:05:52,810 --> 00:05:56,260
in order to fully understand really how it works,
110
00:05:56,260 --> 00:05:58,790
but in Node.js and Express development,
111
00:05:58,790 --> 00:06:01,010
in the real environment you usually
112
00:06:01,010 --> 00:06:03,440
will not want to reinvent the wheel,
113
00:06:03,440 --> 00:06:05,340
and instead, whenever you can,
114
00:06:05,340 --> 00:06:08,810
use packages that other developers have written for us.
115
00:06:08,810 --> 00:06:12,110
So really we just focus on making our application work,
116
00:06:12,110 --> 00:06:14,740
instead of rewriting code that other developers
117
00:06:14,740 --> 00:06:17,750
have already written for us, all right?
118
00:06:17,750 --> 00:06:20,070
So we can take a look at all of this,
119
00:06:20,070 --> 00:06:23,930
but as I mentioned, we can also just go ahead
120
00:06:23,930 --> 00:06:27,110
and actually use this, all right?
121
00:06:27,110 --> 00:06:31,190
Anyway, this is how we enable cross-origin resource sharing
122
00:06:31,190 --> 00:06:32,890
for all incoming requests.
123
00:06:32,890 --> 00:06:35,560
So basically for our entire API.
124
00:06:35,560 --> 00:06:37,950
But let's say we only wanted to enable CORS
125
00:06:37,950 --> 00:06:39,490
on a specific route.
126
00:06:39,490 --> 00:06:43,253
So we could use that as well, so let's just copy this.
127
00:06:44,310 --> 00:06:48,250
And so if we only wanted to enable CORS,
128
00:06:48,250 --> 00:06:50,360
let's say on the tours, well,
129
00:06:50,360 --> 00:06:53,930
we could simply add that here into this middleware stack.
130
00:06:53,930 --> 00:06:56,930
All right, but again in this case
131
00:06:56,930 --> 00:06:59,233
we really want to allow it everywhere.
132
00:07:00,210 --> 00:07:03,400
So as we saw previously in the GitHub code,
133
00:07:03,400 --> 00:07:04,980
what this does is to set
134
00:07:04,980 --> 00:07:09,980
the Access-Control-Allow-Origin header to everything.
135
00:07:14,120 --> 00:07:16,040
And so what this everything here means
136
00:07:16,040 --> 00:07:19,670
is for all the requests no matter here they are coming from.
137
00:07:19,670 --> 00:07:22,350
And so this is ideal for allowing everyone
138
00:07:22,350 --> 00:07:24,380
to consume our API.
139
00:07:24,380 --> 00:07:25,940
But now imagine the case
140
00:07:25,940 --> 00:07:28,440
where we don't want to share our API,
141
00:07:28,440 --> 00:07:31,590
but we want to be able to have the API on one domain,
142
00:07:31,590 --> 00:07:33,960
or even one subdomain, and then have
143
00:07:33,960 --> 00:07:36,760
our front-end application on a different domain.
144
00:07:36,760 --> 00:07:40,580
For example, let's say, so as I mentioned before,
145
00:07:40,580 --> 00:07:45,580
we had our API at API.natours.com,
146
00:07:46,020 --> 00:07:50,290
but then our front-end app at natours.com.
147
00:07:50,290 --> 00:07:52,210
And so in that case all we want it to do
148
00:07:52,210 --> 00:07:56,290
is to allow access from this origin here, basically.
149
00:07:56,290 --> 00:08:01,290
And so in that case we would use app.use,
150
00:08:01,700 --> 00:08:06,700
and then CORS, and then pass in an object for the options
151
00:08:06,719 --> 00:08:08,720
where we'd specify the origin
152
00:08:11,320 --> 00:08:16,320
to let's say HTTPS://www.natours.com.
153
00:08:19,547 --> 00:08:21,560
And so this is just an example
154
00:08:21,560 --> 00:08:26,560
in case we had our front-end at natours.com, all right?
155
00:08:28,870 --> 00:08:31,510
And so again, with this we would only allow
156
00:08:31,510 --> 00:08:34,210
this URL basically, so this origin,
157
00:08:34,210 --> 00:08:39,142
to create requests to API.natours.com.
158
00:08:39,142 --> 00:08:42,070
And of course we could also allow other origins.
159
00:08:42,070 --> 00:08:44,400
For example, only for some specific websites
160
00:08:44,400 --> 00:08:46,770
that we want it to allow, okay?
161
00:08:46,770 --> 00:08:50,690
But again, in this case we really want to allow everyone.
162
00:08:50,690 --> 00:08:54,560
Okay, so this was the first part of enabling CORS,
163
00:08:54,560 --> 00:08:56,940
but actually that's not all,
164
00:08:56,940 --> 00:08:59,160
because right now this will only work
165
00:08:59,160 --> 00:09:01,410
for so-called simple requests.
166
00:09:01,410 --> 00:09:05,280
And simple requests are get and post requests.
167
00:09:05,280 --> 00:09:08,770
On the other hand, we have so-called non-simple requests.
168
00:09:08,770 --> 00:09:12,300
And these are put, patch and delete requests,
169
00:09:12,300 --> 00:09:14,840
or also requests that send cookies
170
00:09:14,840 --> 00:09:17,210
or use nonstandard headers.
171
00:09:17,210 --> 00:09:19,240
And these non-simple requests,
172
00:09:19,240 --> 00:09:22,490
they require a so-called preflight phase.
173
00:09:22,490 --> 00:09:25,520
So whenever there is a non-simple request,
174
00:09:25,520 --> 00:09:27,910
the browser will then automatically issue
175
00:09:27,910 --> 00:09:31,370
the preflight phase, and this is how that works.
176
00:09:31,370 --> 00:09:34,240
So before the real request actually happens,
177
00:09:34,240 --> 00:09:36,480
and let's say a delete request,
178
00:09:36,480 --> 00:09:39,640
the browser first does an options request
179
00:09:39,640 --> 00:09:42,400
in order to figure out if the actual request
180
00:09:42,400 --> 00:09:44,150
is safe to send.
181
00:09:44,150 --> 00:09:46,410
And so what that means for us developers
182
00:09:46,410 --> 00:09:49,410
is that on our server we need to actually respond
183
00:09:49,410 --> 00:09:51,420
to that options request.
184
00:09:51,420 --> 00:09:54,860
And options is really just another HTTP method,
185
00:09:54,860 --> 00:09:59,110
so just like get, post or delete, all right?
186
00:09:59,110 --> 00:10:02,530
So basically when we get one of these options requests
187
00:10:02,530 --> 00:10:05,080
on our server, we then need to send back
188
00:10:05,080 --> 00:10:08,120
the same Access-Control-Allow-Origin header.
189
00:10:08,120 --> 00:10:10,430
And this way the browser will then know
190
00:10:10,430 --> 00:10:11,930
that the actual request,
191
00:10:11,930 --> 00:10:15,520
and in this case the delete request, is safe to perform,
192
00:10:15,520 --> 00:10:20,070
and then executes the delete request itself, all right?
193
00:10:20,070 --> 00:10:24,513
So let's do that and say app.options.
194
00:10:26,130 --> 00:10:29,200
Okay, and so again this is very similar
195
00:10:29,200 --> 00:10:34,200
to doing app.get for example, or .post, .delete, .patch,
196
00:10:35,430 --> 00:10:37,850
and all these verbs that you already know.
197
00:10:37,850 --> 00:10:42,490
So .options is not to set any options on our application,
198
00:10:42,490 --> 00:10:46,490
it's really just another HTTP method that we can respond to.
199
00:10:46,490 --> 00:10:49,670
And so again, in this case we need to respond to it
200
00:10:49,670 --> 00:10:52,010
because the browser sends an option request
201
00:10:52,010 --> 00:10:54,630
when there is a preflight phase.
202
00:10:54,630 --> 00:10:56,520
So we need to define the route
203
00:10:56,520 --> 00:10:59,630
for which we want to handle the options.
204
00:10:59,630 --> 00:11:04,630
And once again, we will do this on all the routes, okay?
205
00:11:04,920 --> 00:11:07,270
And then basically the handler,
206
00:11:07,270 --> 00:11:11,653
which once more is the CORS middleware, all right?
207
00:11:12,610 --> 00:11:15,370
And once more, we could of course only allow
208
00:11:15,370 --> 00:11:18,810
these complex requests on just a specific route.
209
00:11:18,810 --> 00:11:22,630
For example app.options,
210
00:11:22,630 --> 00:11:27,630
and let's say only on api/v1/tours/:id,
211
00:11:31,110 --> 00:11:34,340
like this, okay?
212
00:11:34,340 --> 00:11:37,730
So let's say that someone does a delete or a patch request
213
00:11:37,730 --> 00:11:39,840
for one of the tours, and only there
214
00:11:39,840 --> 00:11:41,890
we allow a preflight phase.
215
00:11:41,890 --> 00:11:44,340
And so basically only on this route here,
216
00:11:44,340 --> 00:11:47,680
one of these complex requests can be done.
217
00:11:47,680 --> 00:11:51,840
So in this case here where we only had this options route,
218
00:11:51,840 --> 00:11:54,150
only the tours could be deleted or patched
219
00:11:54,150 --> 00:11:56,820
from a cross-origin request, right?
220
00:11:56,820 --> 00:11:59,870
And none of our other resources, all right?
221
00:11:59,870 --> 00:12:04,000
But once more, let's allow all of them, okay?
222
00:12:04,000 --> 00:12:07,960
But I will still just leave this here for you as an example.
223
00:12:07,960 --> 00:12:11,550
Okay, anyway, that's all we really have to do
224
00:12:11,550 --> 00:12:14,410
in order to enable CORS for our application.
225
00:12:14,410 --> 00:12:17,030
And so let's now redeploy the application
226
00:12:17,030 --> 00:12:19,620
by pushing it again to Heroku.
227
00:12:19,620 --> 00:12:23,010
But before we do that, I actually want to change
228
00:12:23,010 --> 00:12:25,520
something here in our package.json.
229
00:12:25,520 --> 00:12:28,010
And that is this node engine here.
230
00:12:28,010 --> 00:12:30,380
So sometimes it can create some problems
231
00:12:30,380 --> 00:12:33,220
when we specify the version like this.
232
00:12:33,220 --> 00:12:35,770
So basically allowing versions to install
233
00:12:35,770 --> 00:12:37,400
that are greater than the version
234
00:12:37,400 --> 00:12:38,930
that we're currently running.
235
00:12:38,930 --> 00:12:40,540
And so what I want to do here
236
00:12:40,540 --> 00:12:43,700
is to say that it should only install version 10,
237
00:12:43,700 --> 00:12:45,493
and not a version after that.
238
00:12:46,560 --> 00:12:50,970
So I do it by saying this caret symbol here,
239
00:12:50,970 --> 00:12:52,470
and then version 10.
240
00:12:52,470 --> 00:12:55,990
And so once more, that's using the semantic versioning,
241
00:12:55,990 --> 00:12:57,770
and so just like here.
242
00:12:57,770 --> 00:13:00,610
Which remember, means that NPM is allowed
243
00:13:00,610 --> 00:13:04,390
to install any of these subversions or patch versions,
244
00:13:04,390 --> 00:13:08,070
but not bump up to the next major version.
245
00:13:08,070 --> 00:13:10,760
And so here what I'm doing is the same, okay?
246
00:13:10,760 --> 00:13:14,350
So I'm currently running Node version 10 something,
247
00:13:14,350 --> 00:13:19,070
and so you can confirm yours by typing node -v,
248
00:13:19,070 --> 00:13:22,060
and so you see that I'm on 10.11 right now.
249
00:13:22,060 --> 00:13:24,270
But probably when you're watching this course,
250
00:13:24,270 --> 00:13:29,250
you're gonna be at least at version 12, maybe even 14 or 16,
251
00:13:29,250 --> 00:13:32,510
depending on how long in the future you are, all right?
252
00:13:32,510 --> 00:13:33,860
And don't worry of course,
253
00:13:33,860 --> 00:13:36,240
everything that I show you here in the course
254
00:13:36,240 --> 00:13:37,550
should still be working fine
255
00:13:37,550 --> 00:13:40,010
for whatever Node version you're using.
256
00:13:40,010 --> 00:13:42,030
So if you're using version 12,
257
00:13:42,030 --> 00:13:46,900
then please go ahead and put the 12 right here, okay?
258
00:13:46,900 --> 00:13:51,170
Anyway, let's now add all the modified files
259
00:13:51,170 --> 00:13:56,163
to the staging area, so git add all.
260
00:13:58,300 --> 00:14:02,053
And then commit them with a meaningful message,
261
00:14:03,670 --> 00:14:05,260
so implemented CORS.
262
00:14:08,707 --> 00:14:11,120
And then get push Heroku master.
263
00:14:14,390 --> 00:14:16,200
And now that takes some time,
264
00:14:16,200 --> 00:14:18,453
so I'll see you when that's done.
265
00:14:21,950 --> 00:14:25,640
So the application is successfully deployed now,
266
00:14:25,640 --> 00:14:28,230
let's just quickly reload here
267
00:14:29,100 --> 00:14:32,550
just to see if it's still working, and indeed it is.
268
00:14:32,550 --> 00:14:37,190
And so now to prove you that it works differently with CORS,
269
00:14:37,190 --> 00:14:38,970
if we do this request here again
270
00:14:38,970 --> 00:14:41,720
it should then actually work, right?
271
00:14:41,720 --> 00:14:45,170
So let's try that, and here we go.
272
00:14:45,170 --> 00:14:48,233
No error this time, let's check x here.
273
00:14:49,750 --> 00:14:53,740
And indeed, it looks like there is something here.
274
00:14:53,740 --> 00:14:57,150
So you see that actually the response is of type CORS,
275
00:14:57,150 --> 00:15:01,053
we have our headers, well, I cannot really see them here.
276
00:15:01,920 --> 00:15:04,010
That doesn't matter, here we also have
277
00:15:04,010 --> 00:15:05,690
just a readable string,
278
00:15:05,690 --> 00:15:08,070
but again that's not important at all.
279
00:15:08,070 --> 00:15:10,450
What matters here is that now we are able
280
00:15:10,450 --> 00:15:15,450
to perform cross-origin requests, so that's fantastic.
281
00:15:15,800 --> 00:15:19,130
Now let me just also show you the actual headers
282
00:15:19,130 --> 00:15:21,260
that the CORS package adds
283
00:15:21,260 --> 00:15:25,610
by just doing some request here in Postman.
284
00:15:25,610 --> 00:15:28,513
So in production, let's now send it.
285
00:15:31,540 --> 00:15:34,240
And so here you see in the response headers
286
00:15:34,240 --> 00:15:37,690
that we actually have this Access-Control-Allow-Origin
287
00:15:37,690 --> 00:15:41,960
set to everything, okay, great.
288
00:15:41,960 --> 00:15:45,000
And so this is how you actually implement
289
00:15:45,000 --> 00:15:47,993
cross-origin resource sharing in your own application.
23135
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.