1
00:00:03,710 --> 00:00:10,135
This is the second part of the Express Sessions Exercise.

2
00:00:10,135 --> 00:00:12,320
We have completed the first part earlier,

3
00:00:12,320 --> 00:00:15,310
where we added support for Express Sessions,

4
00:00:15,310 --> 00:00:20,340
and use Express Sessions as a way of tracking the users on the server side,

5
00:00:20,340 --> 00:00:24,160
and recognizing the incoming requests from the users.

6
00:00:24,160 --> 00:00:30,930
In this exercise, we're not concentrating so much on Express Sessions themselves,

7
00:00:30,930 --> 00:00:36,605
but we will look at a way of extending our express REST API server to support

8
00:00:36,605 --> 00:00:42,435
a new model for registering and authenticating users.

9
00:00:42,435 --> 00:00:48,635
So, we will introduce a new user model and schema into our application.

10
00:00:48,635 --> 00:00:52,295
We already have the slash users route which

11
00:00:52,295 --> 00:00:57,290
the express generator has already mounted a user's router.

12
00:00:57,290 --> 00:01:00,035
So, we're going to leverage that and then update that

13
00:01:00,035 --> 00:01:03,205
to support registration of new users,

14
00:01:03,205 --> 00:01:05,390
authenticating an existing user,

15
00:01:05,390 --> 00:01:11,695
and also logging out a user from our server site.

16
00:01:11,695 --> 00:01:17,915
So, we'll look at Express Sessions as a way of tracking the users once the user logs in,

17
00:01:17,915 --> 00:01:19,820
and then when the user logs out,

18
00:01:19,820 --> 00:01:22,680
the session will be removed from the system.

19
00:01:22,680 --> 00:01:27,480
So, how do we go about doing this extension in this exercise?

20
00:01:27,480 --> 00:01:29,700
Let's go and find out.

21
00:01:29,800 --> 00:01:35,485
Continuing with our express REST API server,

22
00:01:35,485 --> 00:01:41,835
let's now go into the models and add a new file named user.js.

23
00:01:41,835 --> 00:01:46,440
This is the file where we will create the user schema and the model.

24
00:01:46,440 --> 00:01:51,405
We'll create a simple user schema which tracks the username and password,

25
00:01:51,405 --> 00:01:55,520
and also a flag that is set to indicate

26
00:01:55,520 --> 00:01:59,540
whether the user is an administrator or a normal user.

27
00:01:59,540 --> 00:02:03,660
So, this is one way of distinguishing among different user types.

28
00:02:03,660 --> 00:02:07,210
So, in this file,

29
00:02:07,210 --> 00:02:16,510
let's first require Mongoose because we are creating a Mongoose schema,

30
00:02:16,510 --> 00:02:26,710
and then we'll create a schema named Mongoose schema,

31
00:02:26,710 --> 00:02:29,720
and then we'll say var user.

32
00:02:29,720 --> 00:02:32,870
So this is the user schema that we're going to create,

33
00:02:32,870 --> 00:02:38,150
and we'll say new user schema.

34
00:02:38,150 --> 00:02:42,740
The user schema will be defined as I just mentioned,

35
00:02:42,740 --> 00:02:47,705
with three fields in here called username

36
00:02:47,705 --> 00:02:55,755
which obviously would be of the type string,

37
00:02:55,755 --> 00:02:59,290
and this is a required field,

38
00:02:59,290 --> 00:03:03,975
and this is a unique field.

39
00:03:03,975 --> 00:03:07,580
You don't want two users with the same username in your system,

40
00:03:07,580 --> 00:03:12,810
so we create the username and then the second field is password field.

41
00:03:12,810 --> 00:03:15,259
Now, of course, you can extend

42
00:03:15,259 --> 00:03:19,820
this user schema to allow the user to track their entire profile,

43
00:03:19,820 --> 00:03:23,985
but we will do that in one of the later exercises, for the moment,

44
00:03:23,985 --> 00:03:30,604
a user is recognized within the system by simply the username and password.

45
00:03:30,604 --> 00:03:36,290
So, the password is of the type string and then is required.

46
00:03:37,300 --> 00:03:44,320
The third field that I'm going to use is called the admin.

47
00:03:44,320 --> 00:03:48,025
So the admin is of the type Boolean,

48
00:03:48,025 --> 00:03:58,270
and we'll say default false.

49
00:03:58,270 --> 00:04:02,905
So, by default when a user is created,

50
00:04:02,905 --> 00:04:04,830
a new user is created,

51
00:04:04,830 --> 00:04:06,855
the admin flag will be set to false.

52
00:04:06,855 --> 00:04:09,925
You can explicitly set it to true from within

53
00:04:09,925 --> 00:04:14,605
your code in order to mark a user as an administrative user.

54
00:04:14,605 --> 00:04:18,460
Perhaps you might provide additional privileges to an administrative user,

55
00:04:18,460 --> 00:04:21,230
or perhaps allowing administrator user to perform

56
00:04:21,230 --> 00:04:24,810
certain operations that normal users would not do so.

57
00:04:24,810 --> 00:04:27,760
We will look at that in one of the later exercises,

58
00:04:27,760 --> 00:04:31,500
for the moment, this is the user schema that we have created,

59
00:04:31,500 --> 00:04:38,150
let's create a module out of this and export from

60
00:04:38,150 --> 00:04:47,075
this module a Mongoose model of the name user.

61
00:04:47,075 --> 00:04:51,115
So, this is the Mongoose model and the schema is

62
00:04:51,115 --> 00:04:55,840
the user schema that we have just defined a little bit earlier.

63
00:04:55,840 --> 00:05:00,615
So, this is how we define our user schema.

64
00:05:00,615 --> 00:05:03,770
So, now that we have defined our user schema,

65
00:05:03,770 --> 00:05:08,660
let's go into the router that has already been set up

66
00:05:08,660 --> 00:05:15,610
by express generator when it generate this express application.

67
00:05:15,610 --> 00:05:17,775
So, if you go into the routes folder,

68
00:05:17,775 --> 00:05:20,890
you will see this file called users.js.

69
00:05:20,890 --> 00:05:26,780
So, this users.js file will be extended to create the router.

70
00:05:26,780 --> 00:05:36,720
So, right there what I am going to do is to import body-parser,

71
00:05:41,510 --> 00:05:46,395
and then they'll declare the express router,

72
00:05:46,395 --> 00:05:50,145
and then we'll say also import

73
00:05:50,145 --> 00:05:57,100
the user schema and

74
00:05:57,100 --> 00:06:03,420
model from models user,

75
00:06:03,950 --> 00:06:09,220
and then for the express router we'll say,

76
00:06:09,220 --> 00:06:13,380
router use body parser.

77
00:06:16,190 --> 00:06:20,690
So, now that we have declared the body parser in there,

78
00:06:20,690 --> 00:06:23,650
we're going to leave this part as such,

79
00:06:23,650 --> 00:06:28,040
later on we will modify this to allow the administrator

80
00:06:28,040 --> 00:06:30,470
to be able to retrieve

81
00:06:30,470 --> 00:06:33,750
all the users that are registered in the system but for the moment,

82
00:06:33,750 --> 00:06:37,705
we're going to leave that route as such.

83
00:06:37,705 --> 00:06:40,500
We will add in a few more routes here,

84
00:06:40,500 --> 00:06:42,965
so we'll say, "Router post."

85
00:06:42,965 --> 00:06:49,970
So we'll support the post operation on a route called signup and as you expect,

86
00:06:49,970 --> 00:06:55,790
this signup route will allow a user to signup on the system,

87
00:06:55,790 --> 00:07:04,920
so this will support the sign up of the user.

88
00:07:04,920 --> 00:07:08,355
So, we'll say, "Rec, res, next."

89
00:07:08,355 --> 00:07:16,090
And so this would be the router post signup,

90
00:07:16,590 --> 00:07:23,410
the remaining methods will not be allowed on the signup end part.

91
00:07:23,410 --> 00:07:25,865
So, to access this,

92
00:07:25,865 --> 00:07:31,420
since this users router is mounted on slash users,

93
00:07:31,420 --> 00:07:35,645
we would specify this endpoint as slash users slash signup,

94
00:07:35,645 --> 00:07:41,765
and this is the end point that will be used to sign up new users within the system.

95
00:07:41,765 --> 00:07:45,080
So, first thing that we will do is use

96
00:07:45,080 --> 00:07:53,300
the user method and the expectation is that for a user to sign up,

97
00:07:53,300 --> 00:07:58,145
the username and password will be provided as a JSON string

98
00:07:58,145 --> 00:08:03,185
inside the body of the incoming post request.

99
00:08:03,185 --> 00:08:05,160
So, from the body,

100
00:08:05,160 --> 00:08:09,200
since the body would have been already parsed by the body parser,

101
00:08:09,200 --> 00:08:10,370
so from the body,

102
00:08:10,370 --> 00:08:13,920
will first check to make sure that

103
00:08:13,920 --> 00:08:22,130
the user with that username doesn't exist within the system.

104
00:08:22,130 --> 00:08:24,380
If the user with that username exist,

105
00:08:24,380 --> 00:08:26,900
then you are trying to sign up a duplicate user

106
00:08:26,900 --> 00:08:29,715
and that should not be allowed in the system.

107
00:08:29,715 --> 00:08:37,340
So, we'll say, "Users find one," and then we'll try to find if

108
00:08:37,340 --> 00:08:41,090
there is one user with the username that has been

109
00:08:41,090 --> 00:08:45,405
selected by the client that is trying to sign up a new user.

110
00:08:45,405 --> 00:08:47,020
If the user already exists,

111
00:08:47,020 --> 00:08:51,850
then obviously you won't allow the new user to sign up with the same username.

112
00:08:51,850 --> 00:08:55,665
So, we'll say, "Then user."

113
00:08:55,665 --> 00:09:03,295
So, this will return the user here and inside this user field,

114
00:09:03,295 --> 00:09:09,080
then we will check for the fact whether the user already exists,

115
00:09:09,080 --> 00:09:12,350
and then let me catch the error here.

116
00:09:12,350 --> 00:09:19,140
So we'll say, "Catch error," and then, "next error."

117
00:09:19,140 --> 00:09:26,160
So, we'll just pass that on to the error handler there.

118
00:09:26,160 --> 00:09:33,345
So, so if this search for the user returns the user field,

119
00:09:33,345 --> 00:09:40,460
if user not equal to null.

120
00:09:40,460 --> 00:09:45,170
So, if the user that is returned by this search is

121
00:09:45,170 --> 00:09:50,510
not null then that means that the user with that given username already exists,

122
00:09:50,510 --> 00:09:53,420
so you should not allow a duplicate signup.

123
00:09:53,420 --> 00:09:58,765
So we'll say, "Var err new error."

124
00:09:58,765 --> 00:10:09,075
And we'll say, "User req. body username."

125
00:10:09,075 --> 00:10:15,410
Already exists. So basically,

126
00:10:15,410 --> 00:10:20,565
you are preventing a duplicate user from signing up and then we'll say

127
00:10:20,565 --> 00:10:29,280
err.status 403 versus the forbidden and then exit,

128
00:10:29,280 --> 00:10:33,735
calling the error handler, next err.

129
00:10:33,735 --> 00:10:36,880
Else, this means that the user doesn't exist

130
00:10:36,880 --> 00:10:39,670
so you should allow the user to be signed off.

131
00:10:39,670 --> 00:10:41,950
So, in the else part,

132
00:10:41,950 --> 00:10:46,150
we will say, return user.Create().

133
00:10:47,200 --> 00:10:56,165
We'll create a new user with the username set to req.body.username,

134
00:10:56,165 --> 00:11:02,555
and then let me put this in the next line so that it's more clear to you,

135
00:11:02,555 --> 00:11:09,620
and we'll say password: req.body.password.

136
00:11:09,620 --> 00:11:14,550
Now, we already know that the admin flag by default will be set to false,

137
00:11:14,550 --> 00:11:17,700
so we're going to leave it as such,

138
00:11:17,730 --> 00:11:28,175
and this will let our new user be signed up and when the new user is signed up,

139
00:11:28,175 --> 00:11:37,880
this will return a promise and inside the "then" we will handle this promise here.

140
00:11:37,880 --> 00:11:41,460
So, this will return the promise from

141
00:11:41,460 --> 00:11:45,625
this "then" and then we'll handle it in the next "then" here.

142
00:11:45,625 --> 00:12:02,120
Will say then, res.statusCode is 200,

143
00:12:02,120 --> 00:12:10,640
res.setHeader and we'll say content-Type application/json

144
00:12:19,830 --> 00:12:38,000
and we'll say, res.json(status: Registration Successful),

145
00:12:42,960 --> 00:12:45,760
and if you want,

146
00:12:45,760 --> 00:12:49,659
we can load the user into

147
00:12:49,659 --> 00:12:58,270
this reply message here as a property in the json.

148
00:13:02,790 --> 00:13:06,890
Will say Registration Successful.

149
00:13:07,830 --> 00:13:14,950
Then if there is an error in

150
00:13:14,950 --> 00:13:22,790
this operation will say "next err".

151
00:13:22,790 --> 00:13:25,200
So that'll handle the error.

152
00:13:25,440 --> 00:13:29,220
If the promise doesn't resolve successfully,

153
00:13:29,220 --> 00:13:32,020
then will be handled by that. So that's it.

154
00:13:32,020 --> 00:13:36,150
So here, we have a way for the user to sign up.

155
00:13:36,150 --> 00:13:38,280
So, for the user to sign up,

156
00:13:38,280 --> 00:13:46,570
the user will do a post on /users/signup and in the body of the message,

157
00:13:46,570 --> 00:13:51,810
the client will include a json string

158
00:13:51,810 --> 00:13:57,760
with username and password properties in that json string.

159
00:13:57,760 --> 00:14:01,200
That's how you sign up for a new user.

160
00:14:01,200 --> 00:14:06,135
Now, let's see how we will login the user.

161
00:14:06,135 --> 00:14:14,605
Now, we will still use the Express sessions that we have done earlier to track the user.

162
00:14:14,605 --> 00:14:24,270
So, to logging a user will say "router.post" on the end point/login.

163
00:14:24,820 --> 00:14:29,370
So on the /login endpoint,

164
00:14:32,280 --> 00:14:35,800
we will do a router.post.

165
00:14:35,800 --> 00:14:42,460
We will obviously instead of saying function,

166
00:14:42,460 --> 00:14:48,575
you can use the arrow function here for the router.post,

167
00:14:48,575 --> 00:14:50,780
I'm going to do the same thing here.

168
00:14:50,780 --> 00:14:53,930
I've gotten fond of arrow functions.

169
00:14:53,930 --> 00:14:57,125
So, we'll do an arrow function here.

170
00:14:57,125 --> 00:15:00,080
So for the login, how does the login proceed?

171
00:15:00,080 --> 00:15:01,880
So for the login,

172
00:15:01,880 --> 00:15:10,850
what we will do is that we will go to the app.js file and then inside this auth,

173
00:15:11,760 --> 00:15:17,050
we were doing that sign up for the user there.

174
00:15:17,050 --> 00:15:20,315
So, what I'm going to do is I'm going to copy

175
00:15:20,315 --> 00:15:25,730
this whole thing because I wouldn't be doing all this anyway.

176
00:15:25,730 --> 00:15:32,970
So, rather let me copy all the way from this point onwards up to the req.session.user.

177
00:15:32,970 --> 00:15:36,925
So, the if part of req.session.user I'm going to copy,

178
00:15:36,925 --> 00:15:44,120
and then coming to the users.js and for the login.

179
00:15:44,120 --> 00:15:47,305
It is exactly how I'm going to do the authentication.

180
00:15:47,305 --> 00:15:51,025
So we'll say if not req.session.user.

181
00:15:51,025 --> 00:15:55,965
So that means that the user has not yet authenticated himself.

182
00:15:55,965 --> 00:15:59,420
Then, you expect the basic authentication as

183
00:15:59,420 --> 00:16:02,780
a mechanism for the user to use for authenticating.

184
00:16:02,780 --> 00:16:07,890
So we'll say var authHeader if!authHeader then we will raise the error,

185
00:16:07,890 --> 00:16:17,760
otherwise we will retrieve the username and password from the header.

186
00:16:17,760 --> 00:16:25,235
Now, here we were doing if username is equal to admin and password is equal to password.

187
00:16:25,235 --> 00:16:30,535
But now, what we're going to do is we're going to search in

188
00:16:30,535 --> 00:16:36,695
the database to see if that particular user exists.

189
00:16:36,695 --> 00:16:39,595
So, instead of doing this here,

190
00:16:39,595 --> 00:16:42,995
instead of doing this if username and password,

191
00:16:42,995 --> 00:16:48,380
we will say, user.findOne

192
00:16:49,650 --> 00:16:56,020
and we'll say username is username.

193
00:16:56,020 --> 00:17:00,730
So this property is equal to this username that we have just retrieved

194
00:17:00,730 --> 00:17:06,820
and then we'll say then user.

195
00:17:09,770 --> 00:17:18,600
So inside this "then".

196
00:17:18,600 --> 00:17:23,110
So I'm going to move this code inside this "then" because

197
00:17:23,110 --> 00:17:28,395
now what I'm going to check for is now that I have retrieved the user,

198
00:17:28,395 --> 00:17:35,625
I need to check to make sure that this user is exactly what I am looking.

199
00:17:35,625 --> 00:17:37,405
So at this point,

200
00:17:37,405 --> 00:17:42,485
we're going to first check to ensure that the user is not null.

201
00:17:42,485 --> 00:17:49,915
So we will say if user is null.

202
00:17:49,915 --> 00:17:51,390
So, if the user is null,

203
00:17:51,390 --> 00:17:55,930
so which means that we couldn't find a user with that particular username.

204
00:17:55,930 --> 00:17:59,860
So, you will have to return an error here.

205
00:17:59,860 --> 00:18:04,540
So let me just copy this part and then paste it in

206
00:18:04,540 --> 00:18:09,840
here and then we'll return saying var new Error

207
00:18:09,840 --> 00:18:14,575
and we'll say

208
00:18:14,575 --> 00:18:23,120
user space username

209
00:18:23,580 --> 00:18:28,750
does not exist.

210
00:18:28,750 --> 00:18:30,600
So in this case,

211
00:18:30,600 --> 00:18:35,230
this user doesn't exist so I'm just going to remove this part and

212
00:18:35,230 --> 00:18:41,840
then the corresponding error status would be 403 here.

213
00:18:42,450 --> 00:18:44,960
So this is the first part.

214
00:18:44,960 --> 00:18:55,000
If the user is null then we are obviously going to tell that the user does not exist.

215
00:18:55,000 --> 00:19:03,780
The second part we're going to check is Else if user password.

216
00:19:03,780 --> 00:19:06,800
So which means that the user exists at this point.

217
00:19:06,800 --> 00:19:12,420
So, the second check that we will do is that the user password is not

218
00:19:12,420 --> 00:19:22,330
equal to password then.

219
00:19:22,330 --> 00:19:25,090
We again need to indicate the error there.

220
00:19:25,090 --> 00:19:28,820
So the error would be saying,

221
00:19:29,790 --> 00:19:34,570
in this case, we'll say

222
00:19:34,570 --> 00:19:41,390
"your password is incorrect".

223
00:19:41,390 --> 00:19:44,085
So that's the second part here.

224
00:19:44,085 --> 00:19:49,650
So your password is incorrect and then the last part.

225
00:19:49,650 --> 00:19:52,515
We will say "else".

226
00:19:52,515 --> 00:19:59,755
So let me indent this code.

227
00:19:59,755 --> 00:20:05,775
So else if user.username

228
00:20:05,775 --> 00:20:15,815
is username which obviously should be true in this case.

229
00:20:15,815 --> 00:20:17,990
Then the second part,

230
00:20:17,990 --> 00:20:27,620
user.password is equal to password which also obviously should be correct at this point.

231
00:20:27,620 --> 00:20:29,720
But in any case,

232
00:20:29,720 --> 00:20:38,885
I'm going to check for that issue here and this else will not occur at all in this case.

233
00:20:38,885 --> 00:20:41,695
So, by the time you reach this point,

234
00:20:41,695 --> 00:20:45,410
the username should be the

235
00:20:45,410 --> 00:20:48,980
same as the username and password should be the same as a password,

236
00:20:48,980 --> 00:20:55,240
but in any case I put in a double-check at that point just to be doubly sure.

237
00:20:55,240 --> 00:20:56,590
Then in this case,

238
00:20:56,590 --> 00:21:02,765
then we'll say req.session.user is authenticated.

239
00:21:02,765 --> 00:21:05,440
So, we will set this to authenticated

240
00:21:05,440 --> 00:21:16,480
and also this one, we will say

241
00:21:16,480 --> 00:21:18,660
res.StatusCode is 200.

242
00:21:18,660 --> 00:21:21,870
So we were successfully able to authenticate the user.

243
00:21:21,870 --> 00:21:29,030
So, we'll say res.StatusCode is 200 and then we'll say res.setHeader

244
00:21:30,540 --> 00:21:43,690
Content-Type text plain and

245
00:21:43,690 --> 00:21:51,500
res.end we'll just simply send a message saying "You are authenticated".

246
00:21:53,700 --> 00:22:00,825
That's it. So, this covers the then part of the user findOne.

247
00:22:00,825 --> 00:22:05,360
So first, we check that if the user is null,

248
00:22:05,360 --> 00:22:07,410
that means that we couldn't find the user,

249
00:22:07,410 --> 00:22:12,025
so we're obviously returning an error saying that the username does not exist.

250
00:22:12,025 --> 00:22:15,195
If the user's password does not match the password,

251
00:22:15,195 --> 00:22:16,450
so at this point,

252
00:22:16,450 --> 00:22:19,150
the user exists but the password didn't match, so we'll say,

253
00:22:19,150 --> 00:22:22,640
"Your password is incorrect", and then, finally,

254
00:22:22,640 --> 00:22:29,050
we reach this point then the username and password should be correctly identified.

255
00:22:29,330 --> 00:22:35,780
Although I don't need this check but I just put it there in place and then at this point,

256
00:22:35,780 --> 00:22:38,680
I will set the req.session.user to authenticate

257
00:22:38,680 --> 00:22:41,830
it and then set the status code to 200 which means that you were

258
00:22:41,830 --> 00:22:48,880
successfully able to authenticate the user and then you can finish at that point.

259
00:22:48,880 --> 00:22:51,490
Because this is a then,

260
00:22:51,490 --> 00:22:54,685
I will put in a catch at this point,

261
00:22:54,685 --> 00:23:03,845
so we'll say catch error and if the error occurs,

262
00:23:03,845 --> 00:23:09,130
then I will simply pass the error over

263
00:23:09,130 --> 00:23:14,560
to the next so

264
00:23:14,560 --> 00:23:20,090
that the error handler will be able to deal with the error appropriately.

265
00:23:20,090 --> 00:23:24,415
So that finishes off this user findOne.

266
00:23:24,415 --> 00:23:31,020
Now, this is the case when the req.session.user is not set.

267
00:23:31,020 --> 00:23:32,905
If that is already set,

268
00:23:32,905 --> 00:23:38,095
then that means that the user is already logged in.

269
00:23:38,095 --> 00:23:40,630
So in this case,

270
00:23:40,630 --> 00:23:50,650
the else part here deals with the situation saying we'll set

271
00:23:50,650 --> 00:23:52,660
the statusCode to 200

272
00:23:52,660 --> 00:24:12,205
and the Content-Type to text/plain and then we'll say,

273
00:24:12,205 --> 00:24:17,680
"You are already authenticated."

274
00:24:17,680 --> 00:24:21,910
So, if you reach this else part,

275
00:24:22,690 --> 00:24:29,060
you would come here because the req.session.user is already not null,

276
00:24:29,060 --> 00:24:32,150
so which means that the user has already been authenticated,

277
00:24:32,150 --> 00:24:34,995
so which means when you reach this point,

278
00:24:34,995 --> 00:24:38,200
then the user has already logged in earlier,

279
00:24:38,200 --> 00:24:41,100
so you don't need to verify.

280
00:24:41,100 --> 00:24:42,220
So you will simply say,

281
00:24:42,220 --> 00:24:46,270
"You're already authenticated," and then finish off at this point.

282
00:24:46,270 --> 00:24:54,975
Okay. So now, the last method that we will implement is for logging out the user.

283
00:24:54,975 --> 00:24:59,180
So, we'll do a router.get on /logout.

284
00:24:59,180 --> 00:25:02,170
You must be wondering why do we do a get on

285
00:25:02,170 --> 00:25:07,000
the logout rather than a post which we did on login?

286
00:25:07,000 --> 00:25:11,090
On login, you need to submit the username and password.

287
00:25:11,090 --> 00:25:14,900
For logout you're simply logging out yourself from the system,

288
00:25:14,900 --> 00:25:17,590
so you don't need to supply any further information because

289
00:25:17,590 --> 00:25:20,910
the server already is tracking you based upon

290
00:25:20,910 --> 00:25:30,665
your session ID and inside that session cookie here.

291
00:25:30,665 --> 00:25:32,620
So, that's why we are not

292
00:25:32,620 --> 00:25:38,890
explicitly needing to send any further information in the body of the message.

293
00:25:38,890 --> 00:25:46,120
So we'll say if req.session so which means that the session must exist,

294
00:25:46,120 --> 00:25:50,070
otherwise, you're trying to log out a user that has not logged in.

295
00:25:50,070 --> 00:25:52,280
So it doesn't make sense.

296
00:25:52,280 --> 00:25:57,490
Now, the session itself provides this method

297
00:25:57,490 --> 00:26:03,415
called destroy and when you call the destroy method,

298
00:26:03,415 --> 00:26:07,520
the session is destroyed and the information is removed

299
00:26:07,520 --> 00:26:12,945
from the server side pertaining to this session.

300
00:26:12,945 --> 00:26:16,970
So, which means that if the client tries to again send

301
00:26:16,970 --> 00:26:19,190
the session information which is stored in the form

302
00:26:19,190 --> 00:26:21,430
of a signed cookie on the client side,

303
00:26:21,430 --> 00:26:22,640
that will be invalid.

304
00:26:22,640 --> 00:26:27,870
So we need a method of deleting the cookie that is stored on the client side.

305
00:26:27,870 --> 00:26:31,110
Now, this operation will remove

306
00:26:31,110 --> 00:26:36,805
the session information from the server side so that the session is no longer valid.

307
00:26:36,805 --> 00:26:38,060
So, at this point,

308
00:26:38,060 --> 00:26:45,115
we'll say req.session.destroy and then we'll say, res.clearCookie.

309
00:26:45,115 --> 00:26:49,640
So the clearCookie is a way of asking the client to

310
00:26:49,640 --> 00:26:54,875
remove the cookie and the cookie name is the session ID.

311
00:26:54,875 --> 00:26:56,630
So, in the previous exercise,

312
00:26:56,630 --> 00:27:00,910
we saw that the cookie was stored with the name of session ID on the client side.

313
00:27:00,910 --> 00:27:05,430
So we are asking the client to delete this cookie from

314
00:27:05,430 --> 00:27:10,935
the client side in the reply message and then we'll say,

315
00:27:10,935 --> 00:27:16,835
res.redirect and we'll redirect it to the homepage here.

316
00:27:16,835 --> 00:27:21,540
So, this is a way of redirecting the user to enter their standard page,

317
00:27:21,540 --> 00:27:24,790
so for example, the homepage of your application.

318
00:27:24,790 --> 00:27:31,090
So, this is the way you would handle the logout of the system.

319
00:27:31,090 --> 00:27:33,200
If the req.session doesn't exist,

320
00:27:33,200 --> 00:27:35,380
then that means that you're not logged in,

321
00:27:35,380 --> 00:27:37,310
so we will have to generate an error.

322
00:27:37,310 --> 00:27:38,945
So we'll say var err,

323
00:27:38,945 --> 00:27:46,370
new Error, "You are not logged in",

324
00:27:47,100 --> 00:27:52,615
and we'll set the error status to 403,

325
00:27:52,615 --> 00:27:54,760
this is a forbidden operation and

326
00:27:54,760 --> 00:28:01,060
then generate the error to the error handler, that's it.

327
00:28:01,060 --> 00:28:08,830
So now, you see that we have extended the user's router to support three new endpoints,

328
00:28:08,830 --> 00:28:13,330
the sign-up endpoint which allows a user to sign up,

329
00:28:13,330 --> 00:28:17,785
the login endpoint which allows a signed up user to login,

330
00:28:17,785 --> 00:28:24,730
and then the logout endpoint which allows a logged in user to log out of the system.

331
00:28:24,730 --> 00:28:26,970
In the process of logging out,

332
00:28:26,970 --> 00:28:29,340
you're destroying the session on the server side,

333
00:28:29,340 --> 00:28:31,890
you're also clearing the cookie on the client side,

334
00:28:31,890 --> 00:28:40,350
so that the client cannot be used in expired session to try to contact that server.

335
00:28:40,350 --> 00:28:43,480
One minor correction in users.js,

336
00:28:43,480 --> 00:28:49,225
this should be var User require../models/user,

337
00:28:49,225 --> 00:28:58,095
recall that the users.js file is in the routes folder and then

338
00:28:58,095 --> 00:29:01,130
the user.js file is in

339
00:29:01,130 --> 00:29:07,440
the models folder which is up one level and then into the models folder.

340
00:29:07,440 --> 00:29:11,620
So, this should be../models/user,

341
00:29:11,620 --> 00:29:15,655
so make that minor correction, that's it.

342
00:29:15,655 --> 00:29:19,040
We have modified the users.js file,

343
00:29:19,040 --> 00:29:23,690
now the last thing that we need to do is go and fix up the app.js file.

344
00:29:23,690 --> 00:29:25,965
In the app app.js file,

345
00:29:25,965 --> 00:29:29,520
if you browse into the app.js file,

346
00:29:29,520 --> 00:29:31,160
you would see that we have

347
00:29:31,160 --> 00:29:37,240
this slash index here and slash users here after the authentication.

348
00:29:37,240 --> 00:29:43,360
Now, this will not work for us because if you need to sign up,

349
00:29:43,360 --> 00:29:49,140
then the user would sign up and log in before the authorization is confirmed,

350
00:29:49,140 --> 00:29:54,910
anyway if the sign up and log in is for the process of signing up,

351
00:29:54,910 --> 00:30:04,295
so I'm going to move these to up before the authentication step here.

352
00:30:04,295 --> 00:30:09,280
So, we're going to move this up into this location.

353
00:30:09,280 --> 00:30:15,430
So thereby, an incoming user can access the index file

354
00:30:15,430 --> 00:30:21,589
at the slash and also access the users endpoint without being authenticated,

355
00:30:21,589 --> 00:30:23,205
but any other endpoint,

356
00:30:23,205 --> 00:30:25,400
the user has to be authenticated,

357
00:30:25,400 --> 00:30:28,665
so that is the way we set this up.

358
00:30:28,665 --> 00:30:32,375
Inside the function authentication, we'll say,

359
00:30:32,375 --> 00:30:40,695
"If not req.session.user," then notice that this place,

360
00:30:40,695 --> 00:30:47,980
we would not be allowing the user to come in here without the user having logged in.

361
00:30:47,980 --> 00:30:50,450
So, if not req.session.user,

362
00:30:50,450 --> 00:30:55,170
then we would simply say you are not authenticated.

363
00:31:03,600 --> 00:31:09,330
This authentication has to be done by using the login method here.

364
00:31:09,330 --> 00:31:13,510
So, I'm going to remove this whole part here.

365
00:31:17,340 --> 00:31:22,285
So, we'll say, if not req.session.user,

366
00:31:22,285 --> 00:31:28,670
we'll say you are not authenticated and so we will have to send a photo three here,

367
00:31:28,670 --> 00:31:31,560
so which means that you should never come down into this point at

368
00:31:31,560 --> 00:31:34,785
all without the user logging in.

369
00:31:34,785 --> 00:31:37,575
So, we'll say you are not authenticated.

370
00:31:37,575 --> 00:31:41,990
Recall that you need to authenticate yourself by doing a POST on

371
00:31:41,990 --> 00:31:47,120
the slash users slash login end point.

372
00:31:47,120 --> 00:31:50,930
So we'll say you are not authenticated, otherwise,

373
00:31:50,930 --> 00:31:56,175
if req.session.user is equal to,

374
00:31:56,175 --> 00:32:01,720
recall that in the login function in the

375
00:32:01,720 --> 00:32:07,780
users.js we have set the next session user to the string authenticated.

376
00:32:07,780 --> 00:32:10,055
So, that is what we are going to be checking for.

377
00:32:10,055 --> 00:32:14,355
We'll say, if req.session.user is authenticated,

378
00:32:14,355 --> 00:32:21,955
we'll say next, else you are not authenticated again.

379
00:32:21,955 --> 00:32:31,990
Then we will send back a forbidden message. That is it.

380
00:32:31,990 --> 00:32:33,995
So, with this update,

381
00:32:33,995 --> 00:32:36,375
my app.js file is also ready.

382
00:32:36,375 --> 00:32:38,590
Now, having done these updates,

383
00:32:38,590 --> 00:32:42,470
let's go and check how our application works now.

384
00:32:42,470 --> 00:32:44,350
Going to the terminal,

385
00:32:44,350 --> 00:32:49,655
if your server is running stop it and then restart your server.

386
00:32:49,655 --> 00:32:51,600
My server is not running at the moment,

387
00:32:51,600 --> 00:32:53,405
so i will say npm start,

388
00:32:53,405 --> 00:32:56,440
and my server should be up and running.

389
00:32:56,440 --> 00:33:00,540
Let's now see how we will access the server.

390
00:33:00,540 --> 00:33:04,150
Going to Postman, let me do a GET on

391
00:33:04,150 --> 00:33:07,290
localhost:3000/dishes and then you will immediately see

392
00:33:07,290 --> 00:33:10,375
that it complains saying you are not authenticated.

393
00:33:10,375 --> 00:33:13,095
Obviously, I'm not authenticated here.

394
00:33:13,095 --> 00:33:19,560
Let me try to access just the localhost:3000 and you will see that,

395
00:33:19,560 --> 00:33:22,625
that root is available for us.

396
00:33:22,625 --> 00:33:29,850
Now, of course, we want to first register a user and then log in

397
00:33:29,850 --> 00:33:37,745
as the user and then thereafter get access to the rest of the REST API endpoints.

398
00:33:37,745 --> 00:33:40,480
So, first, let me register a user.

399
00:33:40,480 --> 00:33:41,925
To register the user,

400
00:33:41,925 --> 00:33:51,410
I need to do a POST to the localhost:3000/users/signup.

401
00:33:53,700 --> 00:33:57,710
For this POST message,

402
00:33:57,930 --> 00:34:01,635
in the body of the message,

403
00:34:01,635 --> 00:34:07,860
I need to include in the body of

404
00:34:07,860 --> 00:34:15,080
the message a JSON string with the username.

405
00:34:15,080 --> 00:34:19,390
So, let me login myself and

406
00:34:19,390 --> 00:34:27,770
then I'll just use the password as password.

407
00:34:28,810 --> 00:34:31,835
This is a valid registration.

408
00:34:31,835 --> 00:34:35,505
So, when I sign up as a user with

409
00:34:35,505 --> 00:34:42,150
this information in the form of a JSON string included in the body of the message,

410
00:34:42,150 --> 00:34:47,590
let me see that the header now contains content type application,

411
00:34:47,590 --> 00:34:50,440
JSON because I've set up the JSON in the body of

412
00:34:50,440 --> 00:34:54,660
the message and then send the POST to the signup.

413
00:34:54,660 --> 00:34:57,175
Then when I send the POST to the signup,

414
00:34:57,175 --> 00:35:02,460
you immediately see what is returned by the server here.

415
00:35:02,460 --> 00:35:05,630
So, you see that the server has returned saying,

416
00:35:05,630 --> 00:35:10,205
"Registration Successful" and itself,

417
00:35:10,205 --> 00:35:13,485
it gives me the details of the user here.

418
00:35:13,485 --> 00:35:19,340
So, this is a record that exists in my MongoDB and

419
00:35:19,340 --> 00:35:25,090
note that the model type is the user model type that we had setup.

420
00:35:25,090 --> 00:35:28,300
So, we have the username and password and

421
00:35:28,300 --> 00:35:33,535
the admin flag as you can see is set to false by default.

422
00:35:33,535 --> 00:35:37,285
Once we register the user,

423
00:35:37,285 --> 00:35:40,370
this user is now a valid user.

424
00:35:40,370 --> 00:35:45,640
So, let me try to again POST the same user and see what happens.

425
00:35:45,640 --> 00:35:48,935
So, when I POST the same user obviously,

426
00:35:48,935 --> 00:35:50,385
there from the server-side,

427
00:35:50,385 --> 00:35:52,840
it replies saying this user already exists.

428
00:35:52,840 --> 00:35:58,480
So, you can see that we have set up our signup procedure to not allow

429
00:35:58,480 --> 00:36:04,580
the user to duplicate register with the same user ID.

430
00:36:04,580 --> 00:36:07,135
Okay. So, that's the second part.

431
00:36:07,135 --> 00:36:13,570
Now, let's do a login of the user.

432
00:36:13,570 --> 00:36:15,770
To do a login of the user,

433
00:36:15,770 --> 00:36:20,400
let me remove the content type and then I will also

434
00:36:20,400 --> 00:36:25,440
remove the body because for the login, that is not required.

435
00:36:25,440 --> 00:36:28,200
So, I don't fill in anything in

436
00:36:28,200 --> 00:36:31,790
the header and then try to login and when I tried to login,

437
00:36:31,790 --> 00:36:34,805
it replies back saying you are not authenticated.

438
00:36:34,805 --> 00:36:36,175
You are unauthorized.

439
00:36:36,175 --> 00:36:39,595
Now, I need to log myself in.

440
00:36:39,595 --> 00:36:42,940
So, this is where I can use the basic authentication.

441
00:36:42,940 --> 00:36:46,240
So, in the basic authentication,

442
00:36:46,240 --> 00:36:51,170
I'm just going to type in my username and

443
00:36:51,170 --> 00:36:56,575
password that I just registered in the previous step and then update my request,

444
00:36:56,575 --> 00:37:00,060
and then do a POST on the login.

445
00:37:00,060 --> 00:37:02,400
So, when I do a POST on the login,

446
00:37:02,400 --> 00:37:06,935
you see that the server replies saying, "You are authenticated".

447
00:37:06,935 --> 00:37:08,740
So, at this point,

448
00:37:08,740 --> 00:37:11,400
I can perform the GET,

449
00:37:11,400 --> 00:37:16,115
PUT, POST and DELETE requests on all the other endpoints.

450
00:37:16,115 --> 00:37:26,370
So, at this point, if I do a GET on the dishes endpoint,

451
00:37:28,760 --> 00:37:32,675
you would see that this returns

452
00:37:32,675 --> 00:37:39,160
the empty field because my database is currently empty at the moment.

453
00:37:39,160 --> 00:37:44,370
Let me clear out the authorization and also from the header remove

454
00:37:44,370 --> 00:37:49,575
the authorization and then do the GET and it's tool box just fine.

455
00:37:49,575 --> 00:37:52,480
So, you can see that I am now able to

456
00:37:52,480 --> 00:37:56,065
access the endpoints because I have logged myself in.

457
00:37:56,065 --> 00:38:00,040
So now, let me do a logout of the user.

458
00:38:00,040 --> 00:38:05,910
So, we'll say, localhost:3000 and logout.

459
00:38:05,910 --> 00:38:08,875
Note also that, in the cookies,

460
00:38:08,875 --> 00:38:12,290
a cookie has been set up at the session ID right there.

461
00:38:12,290 --> 00:38:17,080
So, that cookie exists on my client site.

462
00:38:17,080 --> 00:38:22,715
So now, let me log myself out by saying GET localhost:3000/users/logout.

463
00:38:22,715 --> 00:38:26,580
So, when I do a log out of the user,

464
00:38:26,580 --> 00:38:29,765
you will immediately see that I am redirected to

465
00:38:29,765 --> 00:38:37,830
that localhost:3000 endpoint and also notice that the cookie is gone.

466
00:38:37,830 --> 00:38:40,140
So, when I look at cookies,

467
00:38:40,140 --> 00:38:42,040
you see that the localhost,

468
00:38:42,040 --> 00:38:46,470
the cookie is gone because from my server side when I do the logout

469
00:38:46,470 --> 00:38:51,495
it sends back a rest clear cookie to the client side and so the cookie is gone.

470
00:38:51,495 --> 00:38:54,555
Now, if I try to do a GET

471
00:38:54,555 --> 00:39:02,480
on the localhost:3000/dishes endpoint,

472
00:39:02,480 --> 00:39:05,899
this will not work because I am not authenticated.

473
00:39:05,899 --> 00:39:11,610
So, this demonstrates to you how you can extend your Express server to

474
00:39:11,610 --> 00:39:17,190
allow users to register themselves and then allow the user to login to the system,

475
00:39:17,190 --> 00:39:19,860
and then also logout from the system.

476
00:39:19,860 --> 00:39:25,520
On the server side you are tracking a logged in user using the session and using

477
00:39:25,520 --> 00:39:28,260
the cookie on the client side and when the user logs

478
00:39:28,260 --> 00:39:31,375
out the cookie is destroyed on the client side.

479
00:39:31,375 --> 00:39:34,540
With this, we complete this exercise.

480
00:39:34,540 --> 00:39:37,390
This is a good time for you to do a Git commit,

481
00:39:37,390 --> 00:39:42,420
with the message, Express sessions part two.