So now I got this running server again,
and now we wanna use this session feature
for actually granting access
to certain areas of our website.
And for this back in demo.js, before we protect admin,
I first of all wanna make sure
we add a new piece of data to the session
if a user did log in successfully.
And the new piece of data which I will add
is actually just a little flag
or a little piece of information that tells us
that this user is authenticated.
And here, you can become creative, but most often,
you simply start storing some user data in a session
like the user ID and maybe also the email,
and then in the future,
you check if that data is part of the session.
And if it is, you know that this user is authenticated.
So therefore here in this login post route here,
once we know that a user did log in successfully,
so here in line 85 in my case,
before I redirect to the admin page,
I actually want to add data to my session.
And with that session middleware added
and this session package,
this is super trivial to do.
On the request object,
you simply have a session property now.
And in this session property,
you actually have a nested object.
And in there,
we got a couple of built-in properties and methods.
For example, we can access the ID of the session,
not of the user, but every session has a unique ID
as shown before on the slides.
And that ID is generated automatically
by the session package,
but we could also reset the package
or also force it to be saved back to the database.
In addition, you can also, for example,
destroy it and delete it,
but you can also add properties which are not listed here,
so you can simply add new pieces of data to the session.
For example, we could add a user property here
and set this equal to an object.
You can set it equal to whatever you want,
but I'll set it to an object here where I store the user ID
and set this to a certain value
and where I wanna store user email
and set this to a certain value.
So I wanna store this user data in the session.
You typically don't wanna store the password here
or anything like this because the data we store here
is not meant to be used for validating this user
or anything like this.
Instead, we just store it to see
that we have a logged in user.
And then we just try to store some user data,
which we might need in the future,
like the ID or the email
for getting user-specific data in other routes.
So here for the ID,
we can simply use this existing user object,
which we fetched before,
and then simply access existingUser._id
and store this in our session,
and also store existingUser.email
so that data that we fetched from the database
now is stored in this session.
And therefore, of course,
it will ultimately also be stored in the database,
but in a different collection, in the sessions collection.
And not in order to find user data there,
but just in order to tell us, as a developer,
that requests coming in connected to this session
with user data stored in it are authenticated requests.
That's why we store this here.
Now we could store more data.
We could add more data to this object,
or we could also add more pieces of data to the session,
like isAuthenticated and set this to true.
We could do this in addition to adding this user object.
It's not necessarily required
because we'll only have that user object
if the user is authenticated, so this is a bit redundant,
but for demo purposes,
we can also store this extra flag here.
And then we now wanna make sure
that this session is written to the database.
And the good thing is that by default, it will be.
Whenever a response is sent thereafter,
Express Session, the package we're using
for managing the sessions here,
will automatically save the session to the database
so we don't have to tell Express Session
to store the session data in the database
or in whichever store you specified.
But if you redirect to a path to a route
that will soon be protected
and that will rely on this session data to be updated,
there is a danger of this redirection being finished
before the data in the database was updated
because saving to the database, as you'll learned,
is an asynchronous task that can take
a couple of seconds or milliseconds.
And redirecting might be faster
than saving the session data to the database.
And therefore, there is a danger that we redirect
the visitor to a protected part of our page,
and theoretically, the user should be able to access
this part because we updated the session
with the appropriate data,
but this session data hasn't been written
to the database yet.
And therefore, when the user reaches the protected website,
he or she will still not be able to access it
because we haven't yet updated
the session data in the database.
And therefore, we're not yet able to verify
that this user is authenticated.
Hence for this exact use case here,
that we store authentication data in the session
and that we then plan on redirecting to a page
that requires that data,
we wanna manually call session.save,
a built-in method on this session object
which will force that data to be saved to the database
and which takes a callback function,
so we pass a function,
in this case an anonymous function to it,
which will only be executed by this session package
once saving finished.
So we know that the code inside this function
will only execute once the session data
has been saved to the database.
And therefore now, I wanna move that redirection code
into this anonymous function here
because then we know that the redirection code
will only execute once the session data
has been written to the database.
And with that, we'll prevent this raise condition
where we might otherwise redirect too early.
I hope this makes sense.
So with that, we update our session,
we save it to the database,
and once that all worked and happened,
we redirect the user to the admin page.
And now of course,
the second part of using sessions for authentication
is that we now check that session data
in the routes that should be protected
to find out whether access should be granted or not,
so that would be here in this admin get route.