#108 Protecting Routes: PART 1 | Authentication & Authorization | A Complete NODE JS Course

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in the last couple of lectures we learned how to authenticate a user by logging him in during sign up and also when the user tries to log in using his email and password we did that by sending a Json web token back to the user's client where it will be saved somewhere in the user's client now the next thing which we need to do is we need to provide access to protected routes to logged in users and restrict unauthorized or not logged in users from accessing these protected routes for example only if a user is logged in then only he should be able to access all the movies or see the details of a given movie if the user is not logged in he should not be able to access any movie in the database so this is the functionality which we are going to implement in this lecture and in the next lecture so this lecture I am going to create it in two parts in this first part we will Implement half of the logic and in the next part we will implement the rest of the logic for this functionality so let's go to vs code and let's say we want to protect this get all movies route that means we only want to allow the logged in users to get access to a list of all the movies for that what we need to do is before running this get all movies Handler function we would need to have some check in place in order to verify if the user is actually logged in or not okay so before calling this get all movies route Handler function first we will check if the user is authorized or not and the best way of doing that is as you already know is to use a middleware function so in this lecture in order to protect routes we are going to create a middleware function which is going to run before each of these handlers so before this Catal movie is Handler before this get movie Handler before this create movie Handler and so on okay so what we need to do is if I go to this movie's route here when we are calling this Kettle movies Handler or this create all movies Handler or this get movie Handler before this route Handler function before this middleware function we are going to use another middleware function which should be called and that middleware it should either return an error if the user is not authenticated that is not logged in or it will call the next middleware function in this stack and the next middleware function in this stack in this case will be this get all movies so if the user is authenticated from that middleware this get all movies will will be called but if the user is not authenticated we will throw an error and that will be handled by the global error handling middleware so let's go ahead and let's create that middleware function and I will create that middle layer function inside this authcontroller.js so here let me make some space and let's go ahead and let's create a function and let's export it for that let's say exports Dot and the function name let's say is going to be protect okay and this function is going to be an async function and it is going to receive a request response and the next function as its argument right because it is a middleware function so it will receive request response and the next function as its argument and since it is an async function we also want to handle the rejected promise and for that instead of using try catch block what I am going to do is I am going to wrap this function within a sync error Handler function okay and here it is a sync error Handler it should be in caps and inside this function we need to check several things the first thing which we need to check is we need to read the token and check if it exists basically when the user will try to access this route if the user is logged in we will receive the token issued for that user with the request so from the request we are going to read that token and check if the token actually exists in the request if the token is not there that means the user is not logged in but if the token exists then what we need to do is we need to validate that token we need to verify that token whether that token is correct or not if the token is valid then we also need to check if the user exists or not because let's say if the user is logged in and immediately after that the user has been deleted from the database for some reason then also the user should not be able to access this route right so we also need to check if the user exists in the database or not and then we will also check if the user changed his password after the token was issued when he logged in and after all these checks if everything is fine then we are simply going to allow user to access this route and this part is very simple all we have to do is we have to call the next function from here and what it will do is it will call the next middleware in this step so for example what we want is before the user can access the schedule movies route before that we want to check if the user is authenticated or not so for that we are going to use this middleware function okay so in here in the movies route.js let's first go ahead and let's require this auth controller let's specify the path here so from here we need to move one folder up in there we have the controllers folder and in there we have our auth controller okay so let me copy this auth controller and before calling this cat all movies route we will first call Protect middleware okay so when we are calling this middleware if everything goes fine in that case this next function will be called and this next function will then call this get all movies middleware but inside this protect function inside this function if anything goes wrong then we are going to throw an error and we will call the global error handling middleware so in that case this get all movies route will not get called and the global error handling middleware will be called okay all right now let's go ahead and let's implement the actual functionality so first we are going to implement this functionality where we are going to read the token from the request and we will check in that request if the token actually exists now how are we going to send the token with the request the common practice to send the token with the request is by using the HTTP headers with the request so on the request header we are going to set a custom header called authorization which is a standard name when we want to send Json web token with the request okay so basically we are going to receive the Json web token with the request header and we are going to call that header as authorization so let me show you how we are going to set that header so let's go to postman and here we are going to make a request to this movies API so basically it is going to return us all the movies in the response right as you can see now while sending this get request to the server to our application here we have this header step and there we can go ahead and we can set a header so basically these are the default headers which will be set by the client the client in this case is Postman here we can also set our own custom header I will call it authorization and the value for this header should always start with b error that's because we are the one who basically poses this token so this is just a convention now after this BR what we can do is we can specify the Json web token so for now let me simply call it as ABCD EFG something like this but later we will use the actual web token this is just for demo so we are going to read this authorization header from there we are going to read the value and from the value we only need this part we don't need b error let's see how we can do that let's go back to vs code and here in order to read the header from the request on the request object we have a header and on that header we will have this authorization header okay so when we will set this authorization header on this request dot header we will have that authorization property so whatever value we will have inside this authorization property we are going to assign it to a variable and I will simply call it test token so if we have specified this authorization header in the request header in that case this value will be returned and it will be assigned to this test token now from that value the actual token is this part right so we need to read that value so let's go back to vs code and let's do that and to do that what we will do is we will write an if statement and in there we will check if this test token exists or not or it is undefined so basically if in the request setup we have not specified this authorization header in that case this expression here it will return undefined so in that case this test token will be undefined but if we have specified the authorization header then its value will be returned and that will be assigned to this test token so basically we want to check if this test token exists or not and if this test token exists we also want to check if the test token starts with b error or not so if the test token exists and if it starts with b error in that case what we want to do is we want to read the actual token value the actual token value is this value so for that we can say test token which will contain the complete value from there we want to split and how do we want to split using a space it will return us an array the first element of that array will be this value this b error and the second element of that array will be this value okay so we want to get this value that means the second element from the array which this expression is going to return and to get the second element of the array index of the second element will be 1 right so this will return us the actual Json web token and we are going to store it in a variable and we are going to call it token okay now since we are creating this token using this const keyword inside this if statement inside this if block it will not be accessible outside of this if block right so let's go ahead and let's create this variable outside of this if block maybe here and from here let's simply remove this const keyword now here we have an error because we are trying to create this variable using const keyword and we have not assigned it here and then we are trying to reassign it so instead of const let's use let here and for now let's simply go ahead and let's log this token in the console okay let's save the changes here let's go to postman and let's make a request here so we are getting all the movies in the response let's go back and here you will notice that undefined has been logged when we are trying to log token and that's because here it should be request dot headers okay let's see if the changes again let's go back to postman and let's make a request again and let's go back to visual studio again and you will see that value that header value has been logged here so from there BR has been removed and only the second part in that Adder value has been logged here so for the authorize header we have set this value and from this value only this value is logged so the value of this token is that header value okay so in this case via specifying some token but it is also possible that we don't set this header this authorization header in that case if I make a request and if I go back to visual studio in that case you can see undefined has been logged that means this token does not exist so if the token does not exist in that case we want to throw an error for that let's use an if statement and let's say if the token does not exist for that before this token I am using this not operator that means if the value of this token is undefined in that case we want to throw an error and in this case we are going to call the next middleware function and to that we will pass a new instance of custom error class okay so here I can simply say new custom error and in there let's specify the error message and there is let's say you are not logged in and the status code will be 401 that means unauthorized so since the user is not logged in he is not authorized to access the route okay so if I save the changes now if I go to the postman here you can see I'm not specifying this authorization header in that case if I make the request we should get this error you are not logged in okay let's go back to vs code so this part is complete let's remove this console.log statement from here and now let's implement this second part which is validating the token so if the token exists in that case we are going to validate that token the token will be not valid if someone has tempered with the data or if the token has expired and to validate this token on the JWT that means on the Json web token Library we have a method called verify so we used the sign method earlier another method which is available on Json web token is verify method to this verify method first we need to specify the token which we want to verify in this case we want to verify this token okay and then we need to specify the secret string using which it will verify this token and the secret string we are storing in this config.in file so basically this secret string so here let's go to this auth controller.js and here let's say process dot in dot name of the environment variable which is secret Str then we can also specify a callback function here if we want and that callback function will be called when the verification process is complete so if you want to execute some logic once the verification is complete you can specify that callback function but I am not going to do that here now this verify it is an asynchronous function it will run asynchronously but this asynchronous function it is not going to return a promise okay so what we want is we want to convert that asynchronous data which we are going to receive to a promise and then we want to use it basically we are going to promisify this function this verify function because as I mentioned it is not going to return a promise and so we are going to promisify it so that it will return a promise and then we can handle that promise accordingly now in order to do that node.js has a built-in promisify function and to use that we need to import the util Library so at the top let's go ahead and let's create a variable let's call it util and let's go ahead and let's require this util Library okay and here we can simply say util dot promise if I and we are going to wrap this function like this so basically this here it is going to return a function which will return a promise and then we are calling that function by using a set of parentheses and passing the required arguments and this expression here it is going to return us the decoded token so I'm going to create a variable and I will simply call it decoded token okay and since it is an async function let's also await for the result and now let's simply go ahead and let's log this decoded token let's go ahead and let's save the changes here and now let's test this out so let's go to postman let's enable this authorization header and here instead of setting some random Json web token what I will do is I'll go here and here we have our actual web token so this web token was issued for this user whose email is John gmail.com okay so let's copy this Json web token and in here for the header let's specify that web token okay let's make a request again and you can already see that here we have an error which says JWT has expired the Json web token here has expired and what is the name of the error it is token expired error so basically the time interval which we have specified here for a web token that is 1 million milliseconds and 1 million millisecond is less than one day so what I will do is I will make it as 10 million milliseconds you can also increase it but let's keep it like that but as you can see when we made this request since the Json web token has expired this line here this verify function it has thrown an error and what is the error it is Json web token expired and the type of the error is the name of the error is token expired error now this error is not being handled right so we can handle that error by using try catch block or we can handle this error in our Global error handling middleware itself and that's what we are going to do so let's open our Global error handling middleware for that let's go to this errorcontroller.js and here we have our Global error handling middleware here let's also handle the Json web token expired error so here we can say error Dot name it is equal to let's go to postman and let's copy this error name okay let's paste it here so if the error is of name token expired error in that case we want to handle that error so we want to set this error and we are going to call a function let's call it handle expired JWT okay and to this let's pass the error object and let's go ahead and let's create this function somewhere up maybe here so let's create a variable and it is called as handle expire at JWT here let's create a function I will simply call the argument as err or okay and from here we want to return a new custom error and let's say the error message is JWT has expired please login again okay and error code is again going to be four zero one unauthorized now currently we are in the development environment so we will not see this error message because this error message it is only going to show us in the production environment so what I will do is I will stop this process here and now I will run this application in the production mode for that we can say npm run and for running the application in the production mode we have created a script start underscore Broad let's run this script so now the application should be running in the production mode now let's go back to postman and let me click on the send button and now you can see this error message JWT has expired please log in again so what we are going to do is let's go here and let's try to login again so let me go ahead and let me log in okay and now we are getting a new Json web token let me copy this one let's go back to this get all movies API and there let me specify that value that new Json web token and now let's click on the send button and now we are getting all the movies back in the response so this Json web token has been verified and it is not expired that's why now we are getting all the movies in the response okay but one more problem which could occur here is let's say in between someone has tempered with the Json web token so to demo that what I will do is I'll go to jwt.io website and here I will paste our own token which we have just copied and there I will simply change this ID to something else so instead of B7 let's say C7 okay so now based on this new ID this Json web token will change right so let me copy this let's go back to postman and now let's use that web token that modified web token that tempered web token and if I click on the send button again an error should occur so you can see we have this error something went wrong please try again later so some error has occurred but since we are in the production mode we are seeing this generic error message so let's go back and let's stop this process and let's start it in development mode so for that I can run this script and PM Run start okay so now the application is running in the development mode Let's go back to postman and let's make this request again and now we should see the actual error message which says invalid signature and the error type is Json web token error okay so since we have tempered with the actual Json web token the signature did not matched and we have this Json web token error so we also want to handle that error so again let's go back to visual studio and let's handle that error as well so let's write another statement there we want to check if error dot name if it is equal to let's go back to postman and let's copy the name of the error which is Json web token error let's specify it here so if this type of error has occurred in that case we want to set this error object to handle JWT error okay and Here Also let's pass the error object and let's go ahead and let's create this function so I'll copy it and here let's go ahead and let's create that function again what we want to do from here we simply want to return an instance of a custom error and here the error message will be invalid Json or invalid token please login again and again here also the status code will be four zero one that means unauthorized okay let's again run this application in production mode so I will simply stop the process and let's go ahead and let's run it in production mode so for that I will run this command start Broad and now the application should be running in production mode now let's go back to postman and since the application is running in production mode if I make a request here you can see this error message invalid token please log in again but if we specify the actual token so let's copy it again from here and let's specify that token in that case we should not have any error and the user should be able to access that request and it should return us all the movies in the response as you can see okay so as you can see here in the auth controller we have created this middleware function and we are using it before we are calling this get all movies route Handler so first this middleware function will be called if there is no error inside this middleware function then only this get all movies middleware will be called but if there is any error inside this middleware function in that case it is going to call the global error handling middleware because if I go to this authcontroller.js you can see that if something wrong is happening for example here if the token does not exist we are calling the global error handling middleware in the same way if the token is not valid we are verifying the token using this verify function if the token is not valid it is going to return an error so again that error will be handled by the global error handling middleware but if everything is okay then only we are calling this next function and it will call the next middleware in this tag which in this case is get all movies I hope it is clear so this is all from this lecture we will Implement these two Logics in our next lecture let me remove this console.log statement from here this was just for demo purpose okay so we will implement this functionality and this functionality in our next lecture all right so this is all from this lecture if you have any questions then feel free to ask it thank you for listening and have a great day
Info
Channel: procademy
Views: 5,665
Rating: undefined out of 5
Keywords: authentication, authorization, express, mongoose, mongodb, node js, node js tutorial, complete node js course
Id: V5ZW9ODtQd4
Channel Id: undefined
Length: 26min 28sec (1588 seconds)
Published: Sat May 13 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.