#111 User Roles and Permission | Authentication & Authorization | A Complete NODE JS Course

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome back so we have implemented authentication for our Express app by allowing users to log into our application so if a user is logged in that means the user is authenticated so this functionality is working just fine moving on let's talk about authorization so sometimes only authenticating a user is not enough after logging in the user might need a role to perform some action for example not all users should be authorized to delete a movie or create or update a movie right so authorization simply means authorizing a user to perform certain extent which not all the users have permission to do in simple words when we have authorization in place for certain routes it basically verifies that the user who is trying to access that route has a permission to do so or not for example the delete route so if a user can access the delete route that means he is authorized to delete the movie from the database right so here authorization basically checks that access for that user so let's go ahead and let's implement this authorization functionality in our Express app and for implementing the authorization functionality the first thing which we need is we need a user role so let's go to this usermodel.js and there in the user schema we are going to add a new field and we will simply call it as role the type of this role field is going to be string now for our application we are going to have a certain role for example we will Define the number of roles which we can have for a user for now in this project since it is very simple project we are only going to have two roles so to specify those roles I will use enum type here and I will specify the rules which we can have for this application so the first rule will be a normal user I will simply call it as user and the second role will be admin okay so we only want these two roles in our application we don't want any other role but if you are creating a large application there you might want to have some more roles right anyway so we only want these two roles and also the default role of a user will be the user so for that I will set the default value here which is going to be user and we are missing a comma here so let's add that let's save the changes here and let's go ahead and let's create some new users but before that let's go to Compass and from there let's delete the existing users because these users do not have a role right so I will delete these users all right so all the users have been deleted from this user's collection let's go to Postman and there here we have this sign up request using this request using this endpoint we can create new users so let's go to this body section here and let's create a new user so the first user which I'm going to create is John and let's say the email is John gmail.com okay password and confirm password let's keep it as test one two three four and let's go ahead and let's specify a role here so let's say John is going to be an admin okay let's go ahead and let's send this request so that user has been created and if you see the role here it is admin now let's go ahead and let's create another user maybe Mark and Mark is going to be a normal user okay I will keep the password as test1234 only and I will remove this role from here so in that case the default role will be set and the default rule is user so let's create this user so you can see this user has been created and the role here is user which means normal user now here if you notice we have a small problem here and the problem is using this sign up endpoint any user can log in as admin that means any user can make a request to this URL and there you can specify the role as admin like this and in this way all the users can make them servers admin so this is one bug which we might need to fix in future but for now I will just keep it like that but in the future we will fix this one all right so now we have two users in our mongodb database Let Me Go and Let me refresh this collection we also have this test 3 here which we have not deleted so let's delete it okay so now we have only two users John and Mark John is an admin and Mark is a normal user now what we want is let's say John is logged into our application and he is trying to access this delete route so if he is able to access this delete route that means he should be able to delete a movie from the database now before we allow a user to delete a movie from the database first we need to check if the user is logged in or not for that we can use this protect middleware before allowing user to delete a movie okay so basically using this protect middleware we will check whether the user is an authenticated user or not and then we also want to check if the user has permission to delete a movie so for that we are going to create another middleware function let's go to this authcontroller.js and just like we have created this protect function we are going to create another middleware function so here let's say exports Dot and I will call this middleware function as Maybe restrict okay and to this we are going to assign a function now what we want is when this restrict function will be called to this restrict function we want to pass some arguments but if we create a middleware function here directly like we are doing here so this function here it is a middleware function to this middleware function we can only pass the request response and next as the argument we cannot pass any other argument to this middleware function right but here in order to check if the user has access to perform certain action we need to pass the user role as the argument to that middleware function but since to a middleware function we cannot pass an argument directly except the request response and the next function what we are going to do is we are going to create a wrapper function here okay so here we are going to create a wrapper function and to this wrapper function we can pass an argument I'll simply call it as role and from within this function we are going to return a middleware function okay and this period function is going to receive the request the response and the next function as its argument so just like any other middleware function okay so instead of calling the middleware function directly we are putting that middleware function inside a wrapper function so this function here it is wrapping this middleware function right so we are calling it as wrapper function and now we will call this wrapper function instead of calling this middleware function so what we will do is let's go to this movies route so after we have authenticated the user we want to authorize him so on the auth controller we have another function called restrict okay so this will authorize the user so once this protect middleware has been executed it will call the next middleware so the next middleware here will be this restrict middleware this restrict function and we need to call that function like this and here we will pass the role so the role for which this action is allowed in this case only admins can delete a movie so we'll pass the role as admin so this admin it will be received here for this role parameter and then inside this middleware function we will write the logic to authorize the user okay so here we simply want to check if the user has the appropriate role to perform an action that means if the user who is trying to delete the movie if he has the admin role because as we have defined here only admin should be able to access this delete route so we want to check if the user who is trying to access this delete route if he has the admin role so that admin that will be assigned to this role parameter and we want to check it with the user role now from where we are going to get the user role because here we don't have any user object or any ID to find the user from the database right we simply have a role that is specified as admin but we don't know the user who is actually trying to get access to this delete route well we do have a way to get that so if you see before this function will be executed before that we are executing this protect middleware so once the execution of this protect middle API is complete then we are calling the next middleware using the next function and then only this middleware this function will be called right now in this protect middleware if you remember we had set the current user the logged in user on the user object of this request so basically on this request we added a new property called user and to that we assigned the currently logged in user so here when the next middleware will be called that means when this middleware will be called at that time this request object will have that user property right so we can use that property of the request object so we can say request dot user dot Zol so if it is equal to the role which we are receiving for this function and here instead of checking if it is equal to let's check if it is not equal to okay so that from this function we can return a error so if the rule of this user if it does not match the value for the role parameter that means in this case if the user rule is not admin in that case let's go ahead and let's create a new error object using our custom error class and here let's say the error message is you do not have permission to perform this section and the status code here will be 403 that stands for forbidden that means the user does not have access to perform this action he is forbidden from performing this action okay and now let's go ahead and let's call the global error handling middleware here by passing this error object to the next function so in this case this next function will call the global error handling middleware all right otherwise if the user role if it is equal to the value which we are receiving for this role parameter in this case if the user rule is admin in that case we want to allow the user to delete the movie so for that we simply need to call the next middleware function in this tag right so when we call this next middleware function in this tag it is going to call this delete movie middleware and inside the Sleep movie we have the logic to delete a movie Object I hope it is clear and this should be it so let's save these changes let's go to postman and there let's first go ahead and let's first login as normal user so Mark is the normal user and for Mark the email ID is Market gmail.com so we are going to login using these credentials but before that let me also open a new tab here and here let's type the URL for the delete API so the URL in this case is going to be this URL let me copy it from here let me paste it here okay here it is going to be a delete request and after this movies we also need to specify the ID of the movie which we want to delete so if I go to this get all movies from here let's pick a movie ID maybe some Test movie so here we have this test movie One let's say we want to delete this movie I will grab the ID of this movie okay let's go here and let's paste it here so basically when we make a delete request to this URL it will delete that movie object with this movie ID from the database now in order to do this first the user should be logged in and he should have permission to delete this movie Object right so for logging in we are going to use the Json web token so for that again let's go to this authorize before that let me save this request and I will save it inside this movies folder okay and I'm going to call it delete movie okay let's save this request now let's go to this authorization section from here let's select the type as BR token and here by default you can already see that JWT is already specified let's save this all right now let's go ahead and let's login using these credentials so now we are logged in as a normal user so this Json web token it will be assigned here to this JWT so as you can see that JWT has been assigned with that value so now if I try to delete this movie let's see what happens you see we are getting this error message you do not have permission to perform the section and the status code is 403 that stands for forbidden but if I go ahead and if I log in as admin so in our case John is admin right and for him also the password is test1234 let me log in as John so this web token will be assigned to John and he will log in and this will be set for the JWT here okay so that new value will be set here now if I try to delete that movie you see we are not getting any error message in the response but now that movie should be deleted so if I go back to get movies the movie name is Test movie one okay so if I make a request again now we should not have that movie so if I scroll down you see that movie is gone now we have XYZ so which was after that movie so that movie is deleted okay so our authorization logic is working as expected now as I mentioned earlier here we are creating a simple express application where we only have two roles user and admin but if you are creating a large application then you might have many other roles for example you might have an operator role a viewer role or something like that and multiple roles can have access to perform same action for example let's say here I have two more roles maybe user admin I will say test role maybe test one role and test two role okay so let's say admin and test one role has access to delete a movie in that case here in the movies route we can specify that admin and also test one has access to delete a movie so these two roles have access to delete a movie but here in this function we are only specifying role parameter so here we can only receive one value right but here multiple rows can have access to perform an action so how are we going to implement that logic that's very simple what I will do is I will simply copy this code from here just for demo purpose I will explain what we can do in that case if you want to use multiple rows to perform an action now here for this role we want to pass multiple values because multiple roles can have access to perform an action right but we don't know how many roles will have access to perform an action so we don't know how many parameters we need to specify here right in that case what we can do is we can use rest parameters rest parameter is a concept which is introduced in es6 and for the rest parameter we can specify three dots before the parameter name and that simply means to this parameter we can pass multiple values and this parameter will be an array in that case so for example when we are passing admin and test one here these two values will be stored inside this role parameter and this role parameter here in that case will be an array and since it is an array here instead of checking the condition like this what we can do is here we can check if the role includes request dot user dot role okay so if this role array includes the user rule in this case this roles array will have admin and test one and the user role here is admin so if that array contains admin in that case we want to call the next middleware because in that case that user will have access to perform that action so here we are going to use the not operator like this so if this role array does not contain the user role in that case we will throw this error okay otherwise if there is role array contains that user role the user who is trying to perform the action in that case we are going to call the next middleware in this stack now this code you can use when you want to allow multiple roles to perform a given action in this case we want both admin and test one role to have access to delete a movie so in that case this code will work but in our case our application is quite small so we don't need that much roles in our application so I will simply comment this code I will keep it for your reference and we will go with this implementation and from the user model also let me go ahead and let me delete these two roles because we don't need it here okay only these two roles should be sufficient for our application if we need any more role in future we will add it here all right so this is all from this lecture if you have any questions from this lecture then feel free to ask it thank you for listening and have a great day
Info
Channel: procademy
Views: 15,341
Rating: undefined out of 5
Keywords: authentication, authorization, express, mongoose, mongodb, node js, node js tutorial, complete node js course
Id: PLn4kBtFurI
Channel Id: undefined
Length: 19min 22sec (1162 seconds)
Published: Tue May 16 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.