We've now generated our Jason Webb token and sent it back to a user once they sign up for new account.
So remember this token right here needs to be included in any follow up request.
We're gonna use that token to identify a user.
Let's first get started by adding in some additional codes where application to kind of validate that
a user is sending us some token and if a user does send us a token that is valid will allow them to
access some protected resource.
So to get started I'm going to flip back over to my index J.S. file inside of here.
I'm gonna go down to that little tester out we put together right here.
So I want to say that we will only allow a user to access this test route if they have a valid Jason
web token.
So I want to add in some code somewhere inside my project.
They'll make sure that a user can only access that if they have a valid token.
So to do so inside my SDR see directory I'm gonna make a new folder called middle wears inside of here.
We're going to create a new file called require off dot J.S. so inside this middleware or this file
we're gonna write out a middleware function.
This is a function that's going to take an incoming request and do some kind of pre processing on it.
So inside of this middleware function we're going to make sure that the user includes some token and
if they do we will allow them to access some given route inside our application.
Otherwise if there is not a valid Jason web token we're going to reject the request and send an error
back to the user.
So to get started inside of here we're going to add in a couple of required statements.
First off I'm going to require in that Jason web token library
I'll also require in Mongoose and from the Mongoose library I'm going to get access to that user model
that we created
then inside of here we're going to define and export a function.
So I'll say module dot exports is going to be an async function.
Make sure you get a sync on their actually we don't need async on here.
Let's take that async off my apologies.
There's going to be just a plain function and it's going to be called with a request a response and
a next function.
So inside this middleware if we determine that a user does successfully have a Jason web token we call
the next function right there.
And that's essentially a signal that the request can move on to the next middleware inside of our chain
of middleware as if there's no other middleware to run then we're going to go ahead and run our ultimate
request handler which in our case is going to be that request handler.
Right there now inside of here we can attempt to authenticate this user the first thing we have to do
is kind of establish a mechanism of how the user is going to share that Jason web token with us.
So for our application we're going to say that whenever a user attempts to authenticate themselves with
us through a Jason web token they have to provide that token right there inside of a very special header.
So inside a postman I'm going to create a new tab and we'll write out an example of what this header
is going to look like.
So I'm going to try making a get request to local host three thousand and then inside my head or section
I'm going to add in a new header called authorisation and then its value will be the word bearer then
a space and then we're going to put our token inside there.
So going to flip back over to these sign up page really quickly I'm going to grab that token right there
without the double quotes I'm going to copy that and then I'll put it in right after that bear right
there.
Like so now double check and make sure that your token does not have any double quotes on it because
if it does this is not going to work correctly.
So this is going to be the mechanism that we use to have a user share their token with our API.
They have to include a header called authorisation and as a value they're going to provide bearer a
space and then the token.
Now anytime that our middleware runs right here we're going to inspect that incoming request we're going
to look for a header called authorization and if a user has provided that header we're going to try
to extract the Jason web token from it and validate that is a genuine token.
So to do so we're going to first pull off the authorization header from wreck dot headers so whenever
an incoming request comes into our server any headers that are attached that requests will be placed
inside this headers property so we're going to pull off the authorization header.
You'll notice that I used a lowercase to a right here.
Even though we provided a uppercase authorization over here so whenever a request comes into express
it automatically down cases or lower cases any header names so casually authorization from our request
will turn into a lowercase a authorization inside of our headers object so then we can immediately say
if a user did not provide an authorization header then this must not be a valid request.
In other words the user has not attempted to prove that they are who they say they're going to immediately
return and I'll return resident status with.
How about like a for a one which is a forbidden air and we'll send back an error message of something
like You must be logged in.
Like so
many claps at sidebars we can see the whole line.
There we go okay.
So if a user gets passed that check then they must have provided a valid token.
So now we can try to extract that token out of this authorization header so to do so we'll say cons
token is going to be authorization just to be clear authorization right there.
Let's put a little note right here actually about right underneath authorization to put a little note
to myself and just say authorization is going to be something like a string that says bearer and then
my Jason web token.
So we need to extract just that token by itself.
So to do so we can say authorization dot replace bearer or then put a space right there.
So make sure you get a space right after the word there and we will replace that with an empty string.
So that should leave us with just the token right there.
So now to validate this token we can call JWT dot verify the first argument is going to be the token
we want to validate the second argument is going to be our secret key and remember our secret key right
now or at least mine is my secret key all capital capitals with underscores between each word.
So I going to put that into JWT dot verify as the second argument.
And then the third argument will be my callback function that will be invoked after Jason web token
has done some validation on that token.
So this is where we want our async.
We're gonna make a a scene callback right here.
Remember I accidently put the async keyword up there my mistake.
So I want async and then my function and this callback function will be called with an error if something
went wrong with the verification process and if everything went OK we'll get our payload so payload
right here is going to be whatever information we stuck in to our Jason Webb token.
So in our case it's going to be an object like that right there in object with a user I.D. and that's
the idea the user as they're stored inside of our database.
Now inside this callback we'll immediately take a look at that air object so we'll say if there was
an error if something went wrong then let's return immediately so we can return a resit status for one
and we'll once again just send back an error message as something like You must be logged in we could
potentially say that the user provided an invalid token.
But in general we usually tried to give users kind of opaque error messages whenever it comes to a verification
or authorization errors because that gives a malicious user that much less information about how they
can kind of circumvent our authorization checks OK it's now after we've verified and made sure that
the user provided a legitimate token we can then attempt to extract the user's idea from that payload.
So we'll say const user I.D. is coming from payload now we can use that user idea right there to look
up our user inside of our users collection from mongo DB.
So to do so we can say const user is going to be a weight user model so capital you user find by I.D.
and we'll pass in our user I.D..
So that's going to tell Mongoose to go and take a look at our Mongo DB collection.
It's going to attempt to find a user inside there with a given I.D. and once it finds it it's going
to assign that user to this user variable.
So now we know exactly who made the request so now we're going to take that user and assign it to our
req object.
Remember this Middleware is called with our incoming request.
Chances are that some other request handlers inside our application might want to have some information
about the given user so we'll attach that user model directly to that request object so that any other
request handler inside of rap can very easily get access to this user model so we'll take that user
and we'll assign it to the rec object on the user property and then after that we've done everything
we need to do inside of our middleware.
So we will call next which is a sign that our middleware is all done running.
We can call the next middleware inside of our chain of middleware.
Okay.
So that's pretty much it.
That's our entire Jason web token middleware that's going to make sure that a user provides a token
whenever they make some kind of request to us.
So now to actually use this thing we'll save this file.
I'm going to require it back into the index J.S. file.
So back inside of index dot J.S. at the very top I will require require off we're going to require that
from the middle where's require auth file
and now we can make use of this inside of any of our different quest handlers.
So remember in our case we want to make sure that we secure this default route right here.
So to use that middleware we'll provide it right before that second request handler.
It's all say require off like so so now whenever someone makes a request to our route route we're going
to first run that middleware.
We're gonna make sure that the user provided a valid Jason web token and if they did well then allow
them to actually access that given route right there that route handler if a valid token was not provided
then the request will be automatically rejected and the user will see an error message.
So now just to make sure that everything really is working correctly rather than just sending back a
message of hi there let's change this into a template string by using back ticks and we'll put inside
of your your email and then I'll put down a set of curly braces like so is req dot user dot email.
So remember we assigned that user model or that user instance to the Rec object.
So we're gonna take that thing and just print out the user's email inside our response and so that will
allow us to really validate that we've identified who a user is.
Okay.
Let's save this and give it a quick test it's going to flip back over to postman back over here.
I'm going to attempt to make a request a get request to local who's 3000 with a header of capital a
authorization and a bearer then a space and then my entire JS on the web token I'm going to send that
and I'll see your email is blah blah blah.
So looks like that definitely work successfully.
Our middleware has extracted that Jason web token extracted the user I.D. out of it use that user I.D.
to find the appropriate user inside of our database and then assign that user model to our rec object
and then our right.
Our request handler ultimately printed out some information about that user incented back inside the
response now to make sure that everything is really working correctly.
I'm going to try making a little change to this chase on web token.
If we change any character inside of here and even the smallest way it's going to make the Jason web
token fail to be validated by our server.
So that means that our server is not going to trust the information inside of here.
So to make a small change I'm just gonna remove that leading e character on there I'll just delete e
like so.
So one very small change that I can immediately revert if I need to.
It's now that I've modified that Jason web token I'll send this again.
And now I see an error that says you must be logged in.
So now the Jason web token is no longer valid.
So we're saying hey get out of here.
We don't want you inside of our server okay.
So it looks like it's working perfectly.
If I put the E back on there once again I can make the request again and I now see my email again.
OK.
So it looks great.
It looks like we now have the ability to actually validate users.
We're making a request to our API.
It's now we've got this all put together.
Let's kind of go back in time here.
I said that we were going to fix up that plain text password that we were storing inside of Mongo DB.
Remember if we go back to our Mongo DB instance over here we've got that plaintext password.
And I'd said that we're going to fix that up but we never did.
Let's take a quick pause right here.
When we come back the next video we're gonna make sure that we don't store our passwords in plain text
anymore.