-: In the last section,
we discussed the need to have
some authentication layer,
that our requests are gonna hit,
before they go to our actual protected routes
or our protected controllers.
We said that we were gonna use a library
called Passport to make that happen,
and we also pulled in that library,
and then we installed it,
and created this passport.js file.
Is a quick reminder,
the purpose of passport is we want to hit this kind of...
we want to answer this question,
is our user logged in or not,
before they hit these controllers, right?
We want to answer that ahead of time
and we wanna centralize all that logic;
make sure it only occurs in one place
as opposed to checking for it all the time
inside of our controllers themselves.
So let's talk a little bit more about
exactly what's gonna go on inside of this file.
I'm gonna pull another diagram up on the screen.
So this one is kind of an exploded view
of the diagram that we were just looking at.
We have some incoming request,
it's going to hit our passport library
where we're going to answer the question
is this user logged in or not?
And then it's gonna go onto the route handler
if the user is currently logged in.
So the passport library that we installed,
we didn't only install passport, right?
We also installed this library called passport-jwt.
So passport is not just a library,
it is a little bit more of an ecosystem.
It is an ecosystem formed by what we call
or referred to as strategies.
And so in this diagram, I've listed two possible strategies.
Passport strategy number one
and passport strategy number two.
In passport, a strategy is a method
for authenticating a user.
So we imported or we installed
one strategy called passport-jwt
that attempts to validate or authenticate a user
by using a JSON Web Token.
We could also install a strategy that would attempt to
verify a user given a username and password.
There are many many many different passport
strategies out there.
And if you want to take a look,
you can go to the passport official website
and look all the different ones they have.
There are strategies for handling like
Facebook login or Twitter or GitHub or Google Login.
All these different login strategies that get encapsulated
in a single library that works as a plugin to passport.
So we grabbed the library specifically
for helping us authenticate users using JWT.
So that's what we're going to be working on in this section.
We're going to set up this JWT strategy that we installed.
We're gonna pass some additional options or just do some
a little bit of configuration inside of it.
So here's what we're going to do,
we're going to first create some number of jwtOptions
to kind of configure this strategy
and put a comment on it.
Set up options for JWT Strategy.
We are then going to create JWT Strategy
and finally,
tell Passport
to use this strategy.
Okay, so kinda a three-step process here.
Let's leave these options as just an empty object right now,
just because it's not gonna make too much sense
if we just go ahead and start throwing data
in here at the start.
Let's write some other code first
and then talk about the options
that we are gonna want to pass in here.
So let's start by creating our JWT strategy.
We're going to create
a jwtLogin object,
that is going to be a new JwtStrategy.
The first argument to this constructor
is going to be our jwtOptions
which we created right here.
And then the second argument is going to
be a function that's going to be called
whenever a user tries to log in with a JWT
or whenever we need to authenticate a user with a JWT Token.
The first argument to this is a payload
and the second is done.
So you might be asking, hopefully you're asking,
well, of course there's a lot of really weird code
on the screen right now.
You might be wondering,
what in the world are these two arguments?
Where are they coming from?
So the payload right here is the decoded JWT token.
Remember in the last,
or just one or two sections ago
in the authentication controller,
it created our JWT Token and we assigned a sub
or subject and issued at timestamp on the token.
This was the token's payload right here.
And so when we get a payload back,
the payload coming from the JWT strategy is going to be
that user ID and that timestamp.
So it's gonna have a sub-property and an issued at property.
The second item on here, done is a callback function
that we need to call depending on whether or not
we are able to successfully authenticate this user.
Okay, so basically what we wanna return from this callback.
So we wanna return,
or I shouldn't say return
but what we want to accomplish in here, what we wanna do;
we want to see if
the user ID
in the payload exists
in our database.
If it does,
call
done with that user
otherwise,
call done without a user object.
Alright, So this is what we're trying to accomplish here.
What's gonna happen is if we successfully find a user
with the ID that we're getting from the Token
'cause remember we encoded the user's ID
as the subject property on the Token.
If we can find that user,
we're going to pass it to this done callback
and it's gonna say, okay we found the user,
it's a valid user, here you go, passport, go to your thing.
So in other words, we're saying they are now authenticated,
they are allowed to have access.
If we cannot find a user with that ID,
we're going to call this done function
without a user object which indicates,
no, this person is not authenticated,
they're not valid, don't let them in.
Alright, so let's write the code out
for these different cases.
On our payload, we have the sub-property, which is the ID.
So let's use our user model
which we already imported at the top.
We'll look through all of our different users
and we'll try to find a user with this given ID.
In the callback,
for the fine by ID call,
we're going to get two arguments.
Err and user.
Remember in this case,
err is gonna be populated only if the search failed.
So like if we don't have access to the database
or something like that.
So if err
return,
done.
Err and false.
In this case, the first argument to done is an error object.
And the second argument should be our user object,
if we found one.
In this case, we would've not found a user
and so we're going to return done with an error object.
And false.
False meaning no, we didn't find a user.
So this person, whoever gave, just made a request.
Whoever's giving us this token, they are not authenticated.
Next, we'll say if we found a user,
call done without an err and that user.
Otherwise, if we did not find a user,
call done
with null because there's not an error,
but call it with false.
So we know that hey, you know, there wasn't an error
in the process of searching for the user
but we did not find a user.
So those would be two separate error cases,
one in which the search failed to occur,
and one in which we did a search
but we couldn't find a user.
Okay, so this is step one right here.
This is look for a user that already exists
with our very particular payload ID.
If they do exist, call done
which is a callback as the part of passport.
And let passport know who the user is.
Otherwise tell passport, no, we didn't find anyone.
This person is not authenticated.
Alright, so before we without turning this
into a super long section,
let's continue in the next section
and talk about what the JWT options up here are.
And we'll do another run through
on all the logic in here and you know,
again what we're trying to accomplish
with this strategy overall.
So I'll see you in the next section.