‫So far in our authentication implementation
‫we have logged users in with a correct password.
‫So basically we completed this first step
‫of the authentication workflow
‫where a JSON web token is created
‫and sent back to the client if the user provides
‫a correct email and password.
‫So next up we will actually implement protected routes.
‫So basically using the created JSON web token
‫in order to give logged in users access to protected routes.
‫And this is the second step of authentication.
‫And so let's now go ahead and implement this functionality.
‫So let's say that we wanted to protect the
‫getAllTours route.
‫So basically only allowing logged in users
‫to get access to a list of all our tours.
‫And what what means is that before running
‫the get all tours handler,
‫so let's take a look at that.
‫Okay, so before running this handle here,
‫we would need to have some check in place
‫in order to verify if the user
‫is actually logged in or not, right?
‫And so the best way of doing that
‫as you already know at this point probably,
‫is to use a middleware function, all right?
‫So in this video, in order to protect routes,
‫we're gonna to create a middleware function which is
‫gonna run before each of these handlers, okay.
‫So a function that is gonna sit right here,
‫so before this functio here can run.
‫And this middleware will then either return an error
‫if the user is not authenticated,
‫so if he's not logged in,
‫or it will call the next middleware
‫which is in this case the getAllTours handler, right?
‫And that than effective protects this route
‫from unauthorized access.
‫So let's go ahead and quickly create
‫that middleware function
‫and then put it here
‫in order to illustrate what I just said.
‫Okay, so here in our auth controller again
‫we will create a new middleware function
‫and it's called protect.
‫All right,
‫and just like before I'm gonna use catchAsync
‫because once more all of these functions
‫are async function actually.
‫All right, and then here of course, our middleware function
‫and for now let's very simply call next here
‫just so that we have actually any body here
‫in this middleware function
‫and then let's go back to our tour routes
‫and then protect this route, okay?
‫So first of all I need to actually require this
‫authentication controller module.
‫So const
‫and then require
‫it's in controllers,
‫and then authController, okay.
‫So now let's plug it in, right here
‫in the getAllTours route.
‫Okay.
‫So authController.protect.
‫Okay.
‫And so right now this middleware function is gonna run first
‫and again, if the user is not authenticated
‫then there will be an error.
‫And of course then the next middleware
‫so the one which actually gets
‫and sends all of the tours will then not be executed.
‫Okay.
‫And so again, this will effectively protect the access
‫to this resource here from users that are not logged in.
‫All right, so let's go back here.
‫Not the user routes,
‫but the auth controller.
‫All right, and now about the implementation of
‫this protect middleware.
‫What exactly will we have to do?
‫Well, let's start by lining out a couple of steps here.
‫All right, and actually first of all we need to mark
‫this function as Async, otherwise we wouldn't really need
‫the catchAsync, right?
‫And you will see why we need this to be an Async function
‫in a second, all right?
‫But now let's actually lay out the steps that we need
‫to take in order to implement this protect middleware.
‫So just like before,
‫I'm gonna put these steps here as comments.
‫First off we need to actually get the token.
‫And check
‫if it's there basically,
‫so checking if it exists.
‫Then next up we need to validate the token.
‫And so this is basically that super important step
‫that we talked about before where the JWT algorithm verifies
‫if the signature is valid
‫or if it's not.
‫And so therefore if the token is valid or not, okay?
‫And so actually let's call this here verification.
‫I think that's what we called it in that slide where we
‫talked about this before, all right.
‫And if you don't really remember how that worked,
‫well you can always go back
‫and re watch that lecture, all right?
‫Then next up, so if the verification was actually successful
‫then we also need to check if the user who's trying
‫to access the route still exists, okay?
‫So check if user still exists,
‫and I will talk more about why each of these steps
‫are necessary once we start implementing them, all right?
‫So for now this may not make so much sense to you,
‫but again I will talk about each stop once we get there.
‫All right?
‫And finally we need to also check
‫if
‫user changed password
‫after the JWT
‫was issued, okay?
‫Well, let's just say token here,
‫we called it token everywhere else, okay?
‫And so only if there was no problems
‫in any of these steps here
‫only then of course next will be called which will then
‫get access to the route that we protected.
‫So in our current example, again, this getAllTours handler.
‫Right?
‫Okay, but let's go back
‫and start implementing our very first step here.
‫So basically getting the token
‫and then check if it actually exists.
‫So a common practice is to send a token using an http header
‫with the request, okay?
‫So let's take a look at how we can set headers in Postman
‫to send him along with the request
‫and then also how we can get access
‫to these headers in Express.
‫And let's actually do that one first.
‫So here in apt.js I think we have this nice middleware here,
‫and so in here let's actually log to the console
‫request.headers,
‫Okay, so we talked about http headers before,
‫and so this is how we can get access to them in Express.
‫Okay, so basically to the request headers,
‫so the ones that a client can send along with their request.
‫Okay, and so here in Postman, let's now actually
‫get to the route that we're actually trying to protect.
‫And then here set a header.
‫And let's just do a test one
‫and set it to jonas, okay?
‫Now I will just send this
‫and here in Express, let's take a look at that.
‫And so indeed here we get an object with all of the headers
‫that are part of the request.
‫So all of this here.
‫And you see that there are a bunch of headers that Postman
‫actually sends automatically along with the request
‫for example, it says the the user-agent is Postman
‫it also sends the host,
‫and some other ones that we're gonna talk about later
‫like accept for example.
‫Now what matters here is actually the header
‫that we set ourselves.
‫Okay, so the test header set to jonas that we just sent
‫in our request.
‫Now to send a JSON web token as a header, there's actually
‫a standard for doing that.
‫So let's go back here, get rid of all of this.
‫And so that standard for sending a token is that we should
‫always use a header called authorization.
‫Okay?
‫So just like this
‫and then the value of that header should always start
‫with Bearer, okay?
‫Because basically we bear, we have, we possess this token
‫and then here the value of the token.
‫So just like this random string that we got before.
‫So let's just leave it her at this as an example,
‫and so let's send that now.
‫And then indeed, we should get it here.
‫Okay.
‫Now Express then automatically turns all header names
‫to lowercase, as you can see here,
‫but of course, our header value here is still the same.
‫Okay, and so basically this piece of the header value
‫is our token.
‫And so that's how we should now read
‫that token from the header.
‫All right?
‫So
‫if
‫there actually is req.headers.authorization,
‫okay,
‫and if it starts basically with this bearer string here
‫okay,
‫so req.headers.authorization
‫and now this is a string and so we can
‫use startsWith on that
‫okay, so this is just normal JavaScript again
‫okay.
‫And so these are the conditions under which we actually want
‫to save a token, okay?
‫So, again, in case that tghe header exists
‫and that its value starts with Bearer, okay.
‫Then in that case we want to say that the token is equal
‫to req.headers.authorization
‫and now how do we actually get this second part
‫of the string?
‫Well, we're basically gonna split the string
‫by this space character, okay,
‫which will then create an array
‫with this Bearer
‫and with this token
‫and so then we're gonna take that part
‫of the array that we want.
‫So split using space,
‫and then from that array we want the second element.
‫All right?
‫Now we can't actually define a variable inside
‫of an if block
‫because const, and let,
‫so the new ES6 variable declaratory are
‫actually block scoped,
‫and so whatever we define in this block here
‫will then not be available outside of it.
‫Okay, and so let's actually do that outside.
‫And then simply reassign this value to the token.
‫Okay.
‫And now, let's log the token to the console
‫just to see if it works.
‫Okay, and in fact let's actually get
‫kind of get a real token here.
‫So the one that we just logged in with.
‫And then put that one here, all right.
‫So send it,
‫and
‫ah! Here we go.
‫So here we have our JSON web token data we just sent along
‫with the request.
‫Let's just quickly turn off this console log here.
‫All right, and then just before we move on
‫let's then actually check if the token actually exists.
‫Okay.
‫So if there is no token
‫well, then, of course we want to create a new error.
‫Right, and so just like before
‫we return from this middleware
‫and call the next one, okay.
‫And now in here, we are then going to create an error
‫and so we will move straight
‫to our global error handling middleware with this error.
‫All right, so if there is no token sent with the request,
‫then that means that we're not logged in.
‫So let's send to the user you are not
‫logged in.
‫Please log in to get access.
‫All right, and now the status code for this
‫kind of of situation is 401
‫which means unauthorized, okay?
‫Not sure if we've used that one before
‫and yeah, actually we did it here as well.
‫Okay, and so this basically means
‫that the data that was sent in the request is correct,
‫but they are not enough basically to get the user access
‫to a resource he is requesting.
‫All right.
‫Just give it a save here
‫and test it out again.
‫So, if we basically take away this header here,
‫then we should straight away go into that error,
‫right?
‫And indeed, you are not logged in,
‫please log in to get access.
‫With 401 unauthorized.
‫Great! So that part is already working.
‫All right, and now just to recap,
‫so right now we are not sending any token along with
‫the request, right?
‫And so of that reason, of course, there is no token, okay?
‫And therefore we create this error,
‫which will then trigger our error handler middleware to send
‫that error back to the client, okay?
‫And then of course we do not get access to all the tours,
‫because of course this middleware runs
‫before the getAllTours controller.
‫And so right now, this really is protected, okay?
‫So it's really working quite nice already at this point.
‫But of course, this is far from enough,
‫because it's not enough to just send a token with a request.
‫It also need to be a valid token.
‫So basically a token where no one tried
‫to change the payload.
‫Okay, and the payload, remember, in our case is always
‫the user_id of the user for which the token was issued.
‫All right, and so next up we need
‫to implement this verification step.
‫But this lecture is already running pretty long
‫and there's still a lot of stuff to do here,
‫and so let's actually leave that for the next video.