1
00:00:02,090 --> 00:00:04,530
So now I got this running server again,

2
00:00:04,530 --> 00:00:06,910
and now we wanna use this session feature

3
00:00:06,910 --> 00:00:08,670
for actually granting access

4
00:00:08,670 --> 00:00:11,083
to certain areas of our website.

5
00:00:11,950 --> 00:00:16,250
And for this back in demo.js, before we protect admin,

6
00:00:16,250 --> 00:00:17,940
I first of all wanna make sure

7
00:00:17,940 --> 00:00:21,030
we add a new piece of data to the session

8
00:00:21,030 --> 00:00:23,990
if a user did log in successfully.

9
00:00:23,990 --> 00:00:26,630
And the new piece of data which I will add

10
00:00:26,630 --> 00:00:29,180
is actually just a little flag

11
00:00:29,180 --> 00:00:32,060
or a little piece of information that tells us

12
00:00:32,060 --> 00:00:34,570
that this user is authenticated.

13
00:00:34,570 --> 00:00:38,590
And here, you can become creative, but most often,

14
00:00:38,590 --> 00:00:42,190
you simply start storing some user data in a session

15
00:00:42,190 --> 00:00:45,340
like the user ID and maybe also the email,

16
00:00:45,340 --> 00:00:46,730
and then in the future,

17
00:00:46,730 --> 00:00:50,010
you check if that data is part of the session.

18
00:00:50,010 --> 00:00:53,663
And if it is, you know that this user is authenticated.

19
00:00:54,590 --> 00:00:58,600
So therefore here in this login post route here,

20
00:00:58,600 --> 00:01:02,330
once we know that a user did log in successfully,

21
00:01:02,330 --> 00:01:05,710
so here in line 85 in my case,

22
00:01:05,710 --> 00:01:08,500
before I redirect to the admin page,

23
00:01:08,500 --> 00:01:12,660
I actually want to add data to my session.

24
00:01:12,660 --> 00:01:15,370
And with that session middleware added

25
00:01:15,370 --> 00:01:17,260
and this session package,

26
00:01:17,260 --> 00:01:19,520
this is super trivial to do.

27
00:01:19,520 --> 00:01:21,310
On the request object,

28
00:01:21,310 --> 00:01:24,550
you simply have a session property now.

29
00:01:24,550 --> 00:01:26,500
And in this session property,

30
00:01:26,500 --> 00:01:29,280
you actually have a nested object.

31
00:01:29,280 --> 00:01:30,113
And in there,

32
00:01:30,113 --> 00:01:34,500
we got a couple of built-in properties and methods.

33
00:01:34,500 --> 00:01:37,810
For example, we can access the ID of the session,

34
00:01:37,810 --> 00:01:41,350
not of the user, but every session has a unique ID

35
00:01:41,350 --> 00:01:43,110
as shown before on the slides.

36
00:01:43,110 --> 00:01:45,660
And that ID is generated automatically

37
00:01:45,660 --> 00:01:47,770
by the session package,

38
00:01:47,770 --> 00:01:49,990
but we could also reset the package

39
00:01:49,990 --> 00:01:54,900
or also force it to be saved back to the database.

40
00:01:54,900 --> 00:01:56,810
In addition, you can also, for example,

41
00:01:56,810 --> 00:01:59,220
destroy it and delete it,

42
00:01:59,220 --> 00:02:02,810
but you can also add properties which are not listed here,

43
00:02:02,810 --> 00:02:06,660
so you can simply add new pieces of data to the session.

44
00:02:06,660 --> 00:02:09,860
For example, we could add a user property here

45
00:02:09,860 --> 00:02:12,360
and set this equal to an object.

46
00:02:12,360 --> 00:02:14,410
You can set it equal to whatever you want,

47
00:02:14,410 --> 00:02:18,540
but I'll set it to an object here where I store the user ID

48
00:02:18,540 --> 00:02:20,420
and set this to a certain value

49
00:02:20,420 --> 00:02:23,200
and where I wanna store user email

50
00:02:23,200 --> 00:02:25,490
and set this to a certain value.

51
00:02:25,490 --> 00:02:28,333
So I wanna store this user data in the session.

52
00:02:29,210 --> 00:02:31,550
You typically don't wanna store the password here

53
00:02:31,550 --> 00:02:34,130
or anything like this because the data we store here

54
00:02:34,130 --> 00:02:37,610
is not meant to be used for validating this user

55
00:02:37,610 --> 00:02:38,790
or anything like this.

56
00:02:38,790 --> 00:02:41,040
Instead, we just store it to see

57
00:02:41,040 --> 00:02:43,920
that we have a logged in user.

58
00:02:43,920 --> 00:02:46,520
And then we just try to store some user data,

59
00:02:46,520 --> 00:02:48,560
which we might need in the future,

60
00:02:48,560 --> 00:02:50,770
like the ID or the email

61
00:02:50,770 --> 00:02:54,790
for getting user-specific data in other routes.

62
00:02:54,790 --> 00:02:56,580
So here for the ID,

63
00:02:56,580 --> 00:02:59,120
we can simply use this existing user object,

64
00:02:59,120 --> 00:03:00,693
which we fetched before,

65
00:03:01,800 --> 00:03:04,787
and then simply access existingUser._id

66
00:03:06,170 --> 00:03:09,010
and store this in our session,

67
00:03:09,010 --> 00:03:12,760
and also store existingUser.email

68
00:03:12,760 --> 00:03:15,490
so that data that we fetched from the database

69
00:03:15,490 --> 00:03:17,860
now is stored in this session.

70
00:03:17,860 --> 00:03:18,870
And therefore, of course,

71
00:03:18,870 --> 00:03:21,780
it will ultimately also be stored in the database,

72
00:03:21,780 --> 00:03:25,430
but in a different collection, in the sessions collection.

73
00:03:25,430 --> 00:03:29,470
And not in order to find user data there,

74
00:03:29,470 --> 00:03:32,570
but just in order to tell us, as a developer,

75
00:03:32,570 --> 00:03:36,300
that requests coming in connected to this session

76
00:03:36,300 --> 00:03:40,350
with user data stored in it are authenticated requests.

77
00:03:40,350 --> 00:03:41,943
That's why we store this here.

78
00:03:43,450 --> 00:03:45,110
Now we could store more data.

79
00:03:45,110 --> 00:03:47,490
We could add more data to this object,

80
00:03:47,490 --> 00:03:51,150
or we could also add more pieces of data to the session,

81
00:03:51,150 --> 00:03:54,780
like isAuthenticated and set this to true.

82
00:03:54,780 --> 00:03:58,310
We could do this in addition to adding this user object.

83
00:03:58,310 --> 00:04:00,580
It's not necessarily required

84
00:04:00,580 --> 00:04:02,710
because we'll only have that user object

85
00:04:02,710 --> 00:04:06,270
if the user is authenticated, so this is a bit redundant,

86
00:04:06,270 --> 00:04:07,560
but for demo purposes,

87
00:04:07,560 --> 00:04:10,143
we can also store this extra flag here.

88
00:04:11,320 --> 00:04:13,760
And then we now wanna make sure

89
00:04:13,760 --> 00:04:16,540
that this session is written to the database.

90
00:04:16,540 --> 00:04:19,920
And the good thing is that by default, it will be.

91
00:04:19,920 --> 00:04:22,950
Whenever a response is sent thereafter,

92
00:04:22,950 --> 00:04:25,620
Express Session, the package we're using

93
00:04:25,620 --> 00:04:27,340
for managing the sessions here,

94
00:04:27,340 --> 00:04:30,620
will automatically save the session to the database

95
00:04:30,620 --> 00:04:33,090
so we don't have to tell Express Session

96
00:04:33,090 --> 00:04:35,610
to store the session data in the database

97
00:04:35,610 --> 00:04:38,890
or in whichever store you specified.

98
00:04:38,890 --> 00:04:43,890
But if you redirect to a path to a route

99
00:04:43,920 --> 00:04:46,930
that will soon be protected

100
00:04:46,930 --> 00:04:51,050
and that will rely on this session data to be updated,

101
00:04:51,050 --> 00:04:55,300
there is a danger of this redirection being finished

102
00:04:55,300 --> 00:04:59,020
before the data in the database was updated

103
00:04:59,020 --> 00:05:01,860
because saving to the database, as you'll learned,

104
00:05:01,860 --> 00:05:04,530
is an asynchronous task that can take

105
00:05:04,530 --> 00:05:07,270
a couple of seconds or milliseconds.

106
00:05:07,270 --> 00:05:09,700
And redirecting might be faster

107
00:05:09,700 --> 00:05:12,210
than saving the session data to the database.

108
00:05:12,210 --> 00:05:15,220
And therefore, there is a danger that we redirect

109
00:05:15,220 --> 00:05:18,540
the visitor to a protected part of our page,

110
00:05:18,540 --> 00:05:21,890
and theoretically, the user should be able to access

111
00:05:21,890 --> 00:05:24,410
this part because we updated the session

112
00:05:24,410 --> 00:05:26,600
with the appropriate data,

113
00:05:26,600 --> 00:05:29,130
but this session data hasn't been written

114
00:05:29,130 --> 00:05:30,360
to the database yet.

115
00:05:30,360 --> 00:05:33,230
And therefore, when the user reaches the protected website,

116
00:05:33,230 --> 00:05:36,530
he or she will still not be able to access it

117
00:05:36,530 --> 00:05:38,480
because we haven't yet updated

118
00:05:38,480 --> 00:05:40,320
the session data in the database.

119
00:05:40,320 --> 00:05:43,193
And therefore, we're not yet able to verify

120
00:05:43,193 --> 00:05:45,483
that this user is authenticated.

121
00:05:46,430 --> 00:05:48,910
Hence for this exact use case here,

122
00:05:48,910 --> 00:05:51,610
that we store authentication data in the session

123
00:05:51,610 --> 00:05:54,700
and that we then plan on redirecting to a page

124
00:05:54,700 --> 00:05:56,800
that requires that data,

125
00:05:56,800 --> 00:06:00,190
we wanna manually call session.save,

126
00:06:00,190 --> 00:06:02,980
a built-in method on this session object

127
00:06:02,980 --> 00:06:06,790
which will force that data to be saved to the database

128
00:06:06,790 --> 00:06:09,750
and which takes a callback function,

129
00:06:09,750 --> 00:06:11,370
so we pass a function,

130
00:06:11,370 --> 00:06:13,870
in this case an anonymous function to it,

131
00:06:13,870 --> 00:06:18,340
which will only be executed by this session package

132
00:06:18,340 --> 00:06:20,930
once saving finished.

133
00:06:20,930 --> 00:06:23,890
So we know that the code inside this function

134
00:06:23,890 --> 00:06:26,980
will only execute once the session data

135
00:06:26,980 --> 00:06:29,023
has been saved to the database.

136
00:06:29,910 --> 00:06:32,960
And therefore now, I wanna move that redirection code

137
00:06:32,960 --> 00:06:35,350
into this anonymous function here

138
00:06:35,350 --> 00:06:37,950
because then we know that the redirection code

139
00:06:37,950 --> 00:06:40,660
will only execute once the session data

140
00:06:40,660 --> 00:06:43,140
has been written to the database.

141
00:06:43,140 --> 00:06:47,120
And with that, we'll prevent this raise condition

142
00:06:47,120 --> 00:06:50,350
where we might otherwise redirect too early.

143
00:06:50,350 --> 00:06:51,903
I hope this makes sense.

144
00:06:53,210 --> 00:06:55,530
So with that, we update our session,

145
00:06:55,530 --> 00:06:56,870
we save it to the database,

146
00:06:56,870 --> 00:06:59,380
and once that all worked and happened,

147
00:06:59,380 --> 00:07:02,880
we redirect the user to the admin page.

148
00:07:02,880 --> 00:07:03,713
And now of course,

149
00:07:03,713 --> 00:07:08,460
the second part of using sessions for authentication

150
00:07:08,460 --> 00:07:11,110
is that we now check that session data

151
00:07:11,110 --> 00:07:13,630
in the routes that should be protected

152
00:07:13,630 --> 00:07:17,430
to find out whether access should be granted or not,

153
00:07:17,430 --> 00:07:20,323
so that would be here in this admin get route.

