1
00:00:02,000 --> 00:00:06,000
So how does authentication work in general?

2
00:00:06,000 --> 00:00:08,000
And then also specifically in React

3
00:00:08,000 --> 00:00:11,000
and the Next.js applications.

4
00:00:12,000 --> 00:00:15,000
The core idea is always the same.

5
00:00:15,000 --> 00:00:17,000
We have our client,

6
00:00:17,000 --> 00:00:20,000
so our browser and the user visiting our page

7
00:00:20,000 --> 00:00:25,000
through that browser and our server serving that page.

8
00:00:25,000 --> 00:00:28,000
The server also is connected to a database

9
00:00:28,000 --> 00:00:33,000
where for example, all our registered users are stored.

10
00:00:33,000 --> 00:00:36,000
Now let's assume a user did already create an account.

11
00:00:36,000 --> 00:00:41,000
And now that same user visits our page and wants to log in.

12
00:00:41,000 --> 00:00:43,000
How does that work?

13
00:00:43,000 --> 00:00:47,000
Well, the user enters some data into a login form

14
00:00:47,000 --> 00:00:50,000
like this form here for example,

15
00:00:50,000 --> 00:00:51,000
in the log-in mode.

16
00:00:51,000 --> 00:00:55,000
So the user enters some data here and clicks log in

17
00:00:55,000 --> 00:00:56,000
When that happens,

18
00:00:56,000 --> 00:01:00,000
we send the request with JavaScript to the server

19
00:01:00,000 --> 00:01:03,000
our request which contains the user data,

20
00:01:03,000 --> 00:01:06,000
email and password for example,

21
00:01:06,000 --> 00:01:10,000
then on the server, we can validate that input.

22
00:01:10,000 --> 00:01:12,000
We can reach out to our database

23
00:01:12,000 --> 00:01:16,000
and see if we find an account for that email address.

24
00:01:16,000 --> 00:01:19,000
And if the entered password matches the password

25
00:01:19,000 --> 00:01:21,000
we find in the database.

26
00:01:21,000 --> 00:01:23,000
And then we sent back a response

27
00:01:23,000 --> 00:01:27,000
which basically says, yes, your credentials were correct.

28
00:01:27,000 --> 00:01:29,000
You are authenticated

29
00:01:29,000 --> 00:01:33,000
or which declines the authentication request.

30
00:01:33,000 --> 00:01:38,000
And then once we sent back that yes or no response

31
00:01:38,000 --> 00:01:39,000
though it's a bit more than that

32
00:01:39,000 --> 00:01:41,000
as you will see in a second.

33
00:01:41,000 --> 00:01:43,000
But once you send it back that response

34
00:01:43,000 --> 00:01:48,000
the client can there after also reach protected routes

35
00:01:48,000 --> 00:01:51,000
and send requests to other endpoints

36
00:01:51,000 --> 00:01:56,000
on our server to our URLs on our server

37
00:01:56,000 --> 00:01:59,000
that might require authentication.

38
00:01:59,000 --> 00:02:02,000
Like for example that profile page.

39
00:02:02,000 --> 00:02:05,000
We're only able to reach it once we are authenticated.

40
00:02:05,000 --> 00:02:10,000
And we also only can change the password if we are.

41
00:02:11,000 --> 00:02:15,000
So if that request is sent to some backend API

42
00:02:15,000 --> 00:02:18,000
that the old password should be replaced with a new one

43
00:02:18,000 --> 00:02:23,000
that kind of request should only be allowed

44
00:02:23,000 --> 00:02:27,000
and fulfilled if the user is authenticated.

45
00:02:27,000 --> 00:02:29,000
So that request which we send here

46
00:02:29,000 --> 00:02:32,000
needs some extra data attached to it

47
00:02:32,000 --> 00:02:35,000
some extra data attached to the request

48
00:02:35,000 --> 00:02:38,000
which in the end tells the backend

49
00:02:38,000 --> 00:02:40,000
that this user is authenticated.

50
00:02:40,000 --> 00:02:44,000
Because anyone could be sending requests to our API,

51
00:02:44,000 --> 00:02:49,000
and hence the request needs to carry some extra permission

52
00:02:49,000 --> 00:02:52,000
which then should be verified on the server.

53
00:02:52,000 --> 00:02:55,000
And that permission part is important.

54
00:02:55,000 --> 00:02:58,000
Because a simple yes or no sent back by the server

55
00:02:58,000 --> 00:03:01,000
to the client would not be enough.

56
00:03:01,000 --> 00:03:05,000
Because we can of course always send a request

57
00:03:05,000 --> 00:03:09,000
to some API and point that requires authentication

58
00:03:09,000 --> 00:03:11,000
and say, "Hey, I'm authenticated."

59
00:03:11,000 --> 00:03:16,000
We can't just believe that as the author of the API

60
00:03:16,000 --> 00:03:20,000
we need some proof that a user is authenticated.

61
00:03:20,000 --> 00:03:22,000
And therefore authentication involves

62
00:03:22,000 --> 00:03:26,000
this exchange of credentials for permission.

63
00:03:26,000 --> 00:03:28,000
But the permission is more

64
00:03:28,000 --> 00:03:30,000
than just a yes or no.

65
00:03:30,000 --> 00:03:32,000
To be precise we can't just save

66
00:03:32,000 --> 00:03:34,000
and use a simple yes,

67
00:03:34,000 --> 00:03:37,000
because of fake yes, could be sent.

68
00:03:37,000 --> 00:03:40,000
We can't just tell our server that we are authenticated

69
00:03:40,000 --> 00:03:43,000
and then request protected data

70
00:03:43,000 --> 00:03:45,000
or perform protected operations.

71
00:03:45,000 --> 00:03:48,000
And therefore, instead we need some proof.

72
00:03:48,000 --> 00:03:51,000
Some proof which con to be faked.

73
00:03:51,000 --> 00:03:54,000
And for this, we've got two main mechanisms.

74
00:03:54,000 --> 00:03:59,000
We got server-side sessions and authentication tokens.

75
00:03:59,000 --> 00:04:02,000
Now these are two common approaches

76
00:04:02,000 --> 00:04:06,000
for solving this problem of unfakable permissions.

77
00:04:06,000 --> 00:04:10,000
The concept of server-side sessions

78
00:04:10,000 --> 00:04:15,000
works such that we store some unique identifier on a server.

79
00:04:15,000 --> 00:04:20,000
So we generate some session ID, which is unique.

80
00:04:20,000 --> 00:04:22,000
And we store that on the server,

81
00:04:22,000 --> 00:04:24,000
for example, in a database.

82
00:04:24,000 --> 00:04:28,000
And we sent that same identifier to the client

83
00:04:28,000 --> 00:04:30,000
that sent us the credentials.

84
00:04:30,000 --> 00:04:35,000
Then on the client, we can store that ID that identifier.

85
00:04:37,000 --> 00:04:39,000
And then we can use that stored identifier

86
00:04:39,000 --> 00:04:43,000
to attach it to requests which we there after are send

87
00:04:43,000 --> 00:04:46,000
to protected resources on the server.

88
00:04:46,000 --> 00:04:49,000
And then the server is always able to extract

89
00:04:49,000 --> 00:04:52,000
that identifier from the incoming requests

90
00:04:52,000 --> 00:04:56,000
check if it's stored that identifier in the database

91
00:04:56,000 --> 00:04:59,000
and if it did grant access,

92
00:04:59,000 --> 00:05:02,000
and if it does not deny access.

93
00:05:02,000 --> 00:05:03,000
Now then only clients

94
00:05:03,000 --> 00:05:07,000
which have does identifier are able to send requests.

95
00:05:07,000 --> 00:05:11,000
Now you might say, okay, but can this identify be stolen?

96
00:05:11,000 --> 00:05:14,000
Well, whilst it's in transit it shouldn't be stolen

97
00:05:14,000 --> 00:05:17,000
because we should be using SSL

98
00:05:17,000 --> 00:05:19,000
for encrypting to connection anyways.

99
00:05:19,000 --> 00:05:22,000
And when it is stored on the client side

100
00:05:22,000 --> 00:05:25,000
it is stored in a cookie typically

101
00:05:25,000 --> 00:05:27,000
and that cookie can be configured

102
00:05:27,000 --> 00:05:31,000
such that it's not accessible through JavaScript

103
00:05:31,000 --> 00:05:34,000
to prevent against cross-site scripting attacks.

104
00:05:34,000 --> 00:05:37,000
And that it is only readable from the server

105
00:05:37,000 --> 00:05:41,000
when it is attached to outgoing requests.

106
00:05:41,000 --> 00:05:44,000
And even if it would be accessible through JavaScript

107
00:05:44,000 --> 00:05:45,000
you should be protecting

108
00:05:45,000 --> 00:05:49,000
against cross-site scripting attacks anyways.

109
00:05:49,000 --> 00:05:52,000
And if you can rule out cross-site scripting attacks

110
00:05:52,000 --> 00:05:56,000
your authentication permission stored

111
00:05:56,000 --> 00:05:59,000
in some client-side storage is pretty secure.

112
00:05:59,000 --> 00:06:02,000
Because only you, the owner of this computer

113
00:06:02,000 --> 00:06:05,000
and the user of this browser are able to view it.

114
00:06:05,000 --> 00:06:08,000
So you could only hack yourself

115
00:06:08,000 --> 00:06:11,000
and some random dude wouldn't be able to just send

116
00:06:11,000 --> 00:06:13,000
a fake request to the server

117
00:06:13,000 --> 00:06:17,000
because whilst you could come up with a random identifier

118
00:06:17,000 --> 00:06:20,000
the server would not know that identifier.

119
00:06:20,000 --> 00:06:23,000
So that's the concept of server-side sessions.

120
00:06:23,000 --> 00:06:26,000
The other concept is about authentication tokens.

121
00:06:26,000 --> 00:06:29,000
It's not that far off.

122
00:06:29,000 --> 00:06:32,000
The idea here is that the server does not store

123
00:06:32,000 --> 00:06:34,000
any identifiers.

124
00:06:34,000 --> 00:06:38,000
Instead, the server creates and signs tokens.

125
00:06:38,000 --> 00:06:42,000
Which in the end are just a random strings you could say.

126
00:06:42,000 --> 00:06:47,000
Random strings which can be unpacked to data packages

127
00:06:48,000 --> 00:06:50,000
so we take various pieces of data

128
00:06:50,000 --> 00:06:52,000
and sign them together more on that in a second.

129
00:06:52,000 --> 00:06:56,000
And then such a token is sent back to the client.

130
00:06:56,000 --> 00:06:58,000
The client can then save that token

131
00:06:58,000 --> 00:07:01,000
and again attach it to outgoing requests

132
00:07:01,000 --> 00:07:04,000
to tell the server that access should be granted.

133
00:07:04,000 --> 00:07:07,000
Now, even though the server does not store

134
00:07:07,000 --> 00:07:11,000
that token in a database or anywhere else

135
00:07:11,000 --> 00:07:14,000
the server knows how it's signed that token.

136
00:07:14,000 --> 00:07:17,000
And I'll come back to that in a second.

137
00:07:17,000 --> 00:07:19,000
So the server will be able to verify

138
00:07:19,000 --> 00:07:23,000
if a token was created by it or not.

139
00:07:23,000 --> 00:07:26,000
And therefore, again if I just come up

140
00:07:26,000 --> 00:07:28,000
with some random token string

141
00:07:28,000 --> 00:07:31,000
and I send this to a server to get access

142
00:07:31,000 --> 00:07:35,000
to some protected resource access would be denied

143
00:07:35,000 --> 00:07:37,000
because the server would not be able

144
00:07:37,000 --> 00:07:40,000
to verify my random string.

145
00:07:40,000 --> 00:07:43,000
Because it wouldn't be a validly signed token

146
00:07:43,000 --> 00:07:45,000
generated by that server.

147
00:07:45,000 --> 00:07:48,000
Now these are the two approaches we have.

148
00:07:48,000 --> 00:07:51,000
Now when we build a single-page application

149
00:07:51,000 --> 00:07:55,000
which we in the end still kind of do with Next.js

150
00:07:55,000 --> 00:07:59,000
then we typically work with tokens instead of sessions.

151
00:07:59,000 --> 00:08:01,000
And there are reasons for that.

152
00:08:01,000 --> 00:08:04,000
For one, pages are served directly and populated

153
00:08:04,000 --> 00:08:08,000
with logic without necessarily hitting the server.

154
00:08:08,000 --> 00:08:11,000
Of course, when working with Next.js,

155
00:08:11,000 --> 00:08:13,000
you can build pages

156
00:08:13,000 --> 00:08:16,000
which use get server-side props

157
00:08:16,000 --> 00:08:19,000
and therefore there will be a request handled

158
00:08:19,000 --> 00:08:22,000
by the server every time that page is being served.

159
00:08:22,000 --> 00:08:26,000
But you will also have many pages which are pre-generated.

160
00:08:26,000 --> 00:08:28,000
And once the user is on your website

161
00:08:28,000 --> 00:08:33,000
many pages won't be fetched from the backend at all

162
00:08:33,000 --> 00:08:34,000
but instead will be loaded

163
00:08:34,000 --> 00:08:39,000
and generated dynamically with front-end JavaScript

164
00:08:39,000 --> 00:08:42,000
because you still have a single-page application

165
00:08:42,000 --> 00:08:46,000
at least for many pages that make up your website

166
00:08:46,000 --> 00:08:49,000
after you initially loaded your first page

167
00:08:49,000 --> 00:08:51,000
then still JavaScript takes over,

168
00:08:51,000 --> 00:08:56,000
React takes over and handles your website.

169
00:08:56,000 --> 00:08:57,000
So that's important.

170
00:08:57,000 --> 00:09:00,000
You don't send a request for every page you visit

171
00:09:00,000 --> 00:09:03,000
because you're not using get server-side props

172
00:09:03,000 --> 00:09:04,000
on every page.

173
00:09:04,000 --> 00:09:08,000
So to server, doesn't see every request which you send

174
00:09:08,000 --> 00:09:11,000
and therefore you load pages without the server

175
00:09:11,000 --> 00:09:13,000
being able to directly find out

176
00:09:13,000 --> 00:09:16,000
if you are authenticated or not.

177
00:09:16,000 --> 00:09:19,000
In addition, backend APIs which be used

178
00:09:19,000 --> 00:09:23,000
for a single-page applications are typically stateless.

179
00:09:23,000 --> 00:09:26,000
They don't care about the individual connected clients.

180
00:09:26,000 --> 00:09:30,000
They don't keep track of all the connected clients.

181
00:09:30,000 --> 00:09:32,000
Instead, the idea is that,

182
00:09:32,000 --> 00:09:35,000
that API can work pretty much on its own.

183
00:09:35,000 --> 00:09:38,000
And it just is able to hand out permissions

184
00:09:38,000 --> 00:09:41,000
to clients who authenticated so that they can then

185
00:09:41,000 --> 00:09:45,000
later request access to protect the resources.

186
00:09:45,000 --> 00:09:49,000
The API itself does not store any extra information

187
00:09:49,000 --> 00:09:52,000
about any connected clients.

188
00:09:52,000 --> 00:09:55,000
And since this is how we build single-page applications

189
00:09:55,000 --> 00:09:59,000
the server is not involved in every request

190
00:09:59,000 --> 00:10:02,000
and every action that's happening on our page

191
00:10:02,000 --> 00:10:06,000
because we handled that with front-end JavaScript

192
00:10:06,000 --> 00:10:10,000
and we have that stateless API connected to the SPA.

193
00:10:10,000 --> 00:10:11,000
And because of all of that,

194
00:10:11,000 --> 00:10:15,000
we could say that we have kind of a detached front-end

195
00:10:15,000 --> 00:10:17,000
and back-end combination.

196
00:10:17,000 --> 00:10:20,000
They do talk to each other sometimes

197
00:10:20,000 --> 00:10:24,000
but not for every action that's going on on the page.

198
00:10:24,000 --> 00:10:27,000
And because that's the case, servers don't save information

199
00:10:27,000 --> 00:10:29,000
about authenticated clients.

200
00:10:29,000 --> 00:10:33,000
And instead clients should get that standalone permission

201
00:10:33,000 --> 00:10:37,000
which allows them to prove that they are authenticated.

202
00:10:37,000 --> 00:10:39,000
And that's why we use these tokens.

203
00:10:39,000 --> 00:10:40,000
And here specifically,

204
00:10:40,000 --> 00:10:44,000
we use a concept called JSON Web Tokens

205
00:10:44,000 --> 00:10:46,000
that is simply the most common form

206
00:10:46,000 --> 00:10:48,000
of authentication token.

207
00:10:48,000 --> 00:10:51,000
And it's simply describes the way the token is generated

208
00:10:51,000 --> 00:10:54,000
though we don't need to care about that too much

209
00:10:54,000 --> 00:10:57,000
because we'll use a third-party library for generating

210
00:10:57,000 --> 00:10:59,000
and signing that token anyways.

211
00:11:00,000 --> 00:11:04,000
So as it seems, these JSON Web Tokens are important

212
00:11:04,000 --> 00:11:06,000
and therefore we should take a closer look at them.

213
00:11:06,000 --> 00:11:11,000
We should understand how exactly JSON Web Tokens work.

214
00:11:11,000 --> 00:11:12,000
And in the end that JSON Web Tokens

215
00:11:12,000 --> 00:11:17,000
is generated with three main blocks.

216
00:11:18,000 --> 00:11:20,000
We got some issuer data.

217
00:11:20,000 --> 00:11:24,000
Some data which is automatically added into a token

218
00:11:24,000 --> 00:11:27,000
by the server when that token is generated.

219
00:11:27,000 --> 00:11:30,000
That's some metadata which we typically don't set up

220
00:11:30,000 --> 00:11:32,000
ourselves as a developer,

221
00:11:32,000 --> 00:11:35,000
but which is pre-configured by the third party packages

222
00:11:35,000 --> 00:11:38,000
we use for generating tokens.

223
00:11:38,000 --> 00:11:42,000
We can then still also add custom data to our token

224
00:11:42,000 --> 00:11:45,000
for example, some information about the user

225
00:11:46,000 --> 00:11:47,000
and then very important,

226
00:11:47,000 --> 00:11:50,000
we also set up a secret key.

227
00:11:50,000 --> 00:11:53,000
We set up that key on the server.

228
00:11:53,000 --> 00:11:56,000
The client never gets to see that key.

229
00:11:56,000 --> 00:11:59,000
And that's important because if you have that key

230
00:11:59,000 --> 00:12:02,000
you can create valid tokens,

231
00:12:02,000 --> 00:12:04,000
which are accepted by the server.

232
00:12:04,000 --> 00:12:08,000
Hence only the server knows that key.

233
00:12:08,000 --> 00:12:12,000
Then we generate a token with some third-party package

234
00:12:12,000 --> 00:12:14,000
by combining all these pieces together

235
00:12:14,000 --> 00:12:19,000
by creating a random string that incorporates all that data

236
00:12:19,000 --> 00:12:21,000
and is signed by that key.

237
00:12:21,000 --> 00:12:23,000
And that is that JSON Web Token,

238
00:12:23,000 --> 00:12:25,000
a long string.

239
00:12:26,000 --> 00:12:28,000
The important thing here is that

240
00:12:28,000 --> 00:12:30,000
signing does not mean encryption.

241
00:12:30,000 --> 00:12:34,000
The JSON Web Token is not encrypted.

242
00:12:34,000 --> 00:12:37,000
You can unpack it and read the data inside of it

243
00:12:37,000 --> 00:12:39,000
without knowing that key.

244
00:12:39,000 --> 00:12:44,000
That key only proves that a given server created that token.

245
00:12:45,000 --> 00:12:48,000
But you can read the content of the token

246
00:12:48,000 --> 00:12:49,000
without knowing that key.

247
00:12:49,000 --> 00:12:53,000
The key of course will not be included in the token though.

248
00:12:53,000 --> 00:12:55,000
So you can't read that key,

249
00:12:55,000 --> 00:12:57,000
even if you unpack the token.

250
00:12:59,000 --> 00:13:02,000
Now is that token which then is stored by the client?

251
00:13:02,000 --> 00:13:03,000
Sorry. By the browser?

252
00:13:03,000 --> 00:13:05,000
And which then is attached

253
00:13:05,000 --> 00:13:09,000
to requests two protected resources on the server.

254
00:13:09,000 --> 00:13:12,000
So two protected API routes.

255
00:13:12,000 --> 00:13:15,000
And for example, if you wanna change our password

256
00:13:15,000 --> 00:13:18,000
we don't just send the old and the new password

257
00:13:18,000 --> 00:13:23,000
but we also include that token in the outgoing request.

258
00:13:23,000 --> 00:13:27,000
And that token then is validated by the server

259
00:13:27,000 --> 00:13:28,000
which basically checks...

260
00:13:28,000 --> 00:13:33,000
Okay. If I would use my signing key which only I know

261
00:13:33,000 --> 00:13:36,000
would I be able to generate this token?

262
00:13:36,000 --> 00:13:38,000
And if the answer is, yes.

263
00:13:38,000 --> 00:13:39,000
The server knows that it's valid.

264
00:13:39,000 --> 00:13:41,000
If the answer is no.

265
00:13:41,000 --> 00:13:44,000
It's invalid and access is denied.

266
00:13:44,000 --> 00:13:47,000
So that's why we can't just generate a token

267
00:13:47,000 --> 00:13:48,000
without knowing the key.

268
00:13:48,000 --> 00:13:51,000
We can't generate a token,

269
00:13:51,000 --> 00:13:52,000
but it would be an invalid one.

270
00:13:52,000 --> 00:13:55,000
And that's why this is a secure mechanism.

271
00:13:56,000 --> 00:13:57,000
Okay. That was a lot of talking

272
00:13:57,000 --> 00:13:58,000
about of all of that,

273
00:13:58,000 --> 00:14:01,000
but that's the important theory.

274
00:14:01,000 --> 00:14:04,000
The foundation we need for then actually diving

275
00:14:04,000 --> 00:14:08,000
into authentication and implementing authentication.

276
00:14:08,000 --> 00:14:09,000
The great news is,

277
00:14:09,000 --> 00:14:13,000
that we don't need to build all these things from scratch

278
00:14:13,000 --> 00:14:15,000
but that instead for the token creation

279
00:14:15,000 --> 00:14:17,000
and validation and so on,

280
00:14:17,000 --> 00:14:21,000
we can rely on secure third-party packages.

