How To Manage User Roles In Node.js

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
imagine your favorite website let's just say for example read it and now imagine that every user on the site has the ability to delete or edit the comments of every other user it would not take even just a couple hours for the entire site to go into complete chaos and the only thing preventing that chaos is a strict strong system of rules and permissions for users so in this video I'm going to show you how to set up a really flexible and really powerful rule and permission system for users inside of nodejs let's get started now now if you create a complex permission system you're gonna need somewhere to host this which is perfect because it will annek that met today's video sponsor is giving you an entire free year-long trial of their servers and these are powerful servers these servers are actually more powerful than you're gonna get in the free trial of most other providers and you're getting them for an entire year instead of 30 days or maybe even 60 days that is 365 days so make sure you check out Atlanta net link down in the description below and use the code Kile to get an additional 50 dollars of credit which you can use towards anything else on the hosting plan welcome back to web dev is simplified my name is Kyle and my job is to simplify the web for you so you can start building your dream project sooner so if that sounds interesting make sure you subscribe to the channel for more videos just like this now to get started I have a very basic boilerplate code setup and if you want you can download this code from the github link in the description below but I'm gonna go through exactly what I have here just so you know exactly where we are so the first file is this data j/s file and this is a really basic file this has all of the different permission rolls in our system for now we just have admin and basic because I just want to show you how this works without dealing with a hundred different permission rules also we have our users which is going to be taking the place of a user database you can imagine that this is just a table inside of a MongoDB database that has these three different users same thing for projects we have three different projects and each user has their own project and I've just given the project the name of the user as well so we can easily see which project is whose and then we also have different rules the Kyle user has a role admin and these other two users have the basic role the next thing that we have is going to be our server jeaious this is our main server in here we're just starting up an Express server we're telling it to use JSON so that way we actually can pull in data from a post request this is essentially an API we're also pulling in our project router and making sure that all of our project routes are set up that way and then we just have a few really basic routes here we have a get route for the home page a dashboard page where the logged in users can see this in an admin page for admins only and then finally we have this middleware which is just setting our user so inside of our body we're going to be passing up a user ID and we're actually setting the user based on that user ID from the data inside that data j/s file and then we're just listening on port 3000 so a really basic server we just have these three routes as well as all of our project routes and inside of our project it's very straight forward we have a get route to get all of the projects and then a route to get just a single project and then this simple route to set the project for this a get route here really pretty basic boilerplate code and I also have this file here called test rest and if you're using an extension called rest client inside of es code you can actually make API requests directly in vs code or you can use something like postman if you want to make the request that way so this test rest file allows me to for example make a request to localhost 3000 if I click send request you see we get the response of home page which is the exact same response we have inside of our server jeaious as you can see res dot send home page and the reason this is working is because i've run npm run dev start which just starts up our server instead of here if we see we have a node monsura jeaious when I run dev start so it just starts up our server and it'll restart it every time we make a change and that's pretty much the basic code we have we essentially have a system with a bunch of different routes but none of these routes are actually protected for example this home page anyone can go to which is okay but this admin page for example if I send a request I'm not logged in no authentication and I still have access to the admin page so we need to make sure that we lock down these different pages based on role as well as based on what projects the user has access to and whether or not the user is logged in so to get started I want to go with the most basic form of authentication which is whether or not the user is logged in that's going to be our very first set of requirement because we have this dashboard page which should be visible to every user as long as they're logged in but right now we aren't logged in as any user so this dashboard page should essentially tell us we need to sign in so let's go into our survey digest and see exactly what we need to do we can open this up here and we can see that we have this dashboard page and we want to write some form of middleware which is going to take in the user which we're setting here so our user is already set its request user and we just want to check if that user exists then continue otherwise make sure that they are logged in and send them an error message and instead of writing this code inside of our service file I want to create a brand new file for this and we're just gonna call this simple file here basic auth is this is going to be for a really basic authentication and we're gonna create a function in here which is going to be called off user and this is just going to be a middleware so it's going to take in a request response and next and this is going to check if the user exists if they're logged in if so continue otherwise throw some form of error so if you remember I said we set our user on request user so we can just say if the request out user is an old then that means we don't have a user so what we want to do is take our response and set the status to be 403 that essentially means that you do not have access to this you're not actually logged in so that you need to log in and then we can return our res dot send and it just says you need to sign in just like that and we can export this by saying module dot exports and we can export that auth user so now we have this function being exported from this file and instead of our server here we can import that auth user function which is coming from oops require of that dot slash basic auth make sure I save both these files and now what we can do is just simply for our dashboard we can just say auth user and now if I try to send a request you're gonna see it says you need to sign in and in order to have a user be sent in we just need to send in some JSON so I'm going to tell the server that our application is sending JSON and then inside it here I'm going to just send the user ID and we have a user ID of 1 if you remember quickly we have 1 2 & 3 so if I send a user idea of 1 and send the request you'll notice it's not actually giving us back a response and that's because in our basic auth I never actually called next so we just need to call next here which is going to talk server to continue to the next piece of middleware which in our case is inside of our server right here to send this dashboard page and now when I click send request you can see I get back dashboard page and if I don't have a user and I click send you see it tells me I need to sign in so we have the most basic form of authentication done where we say only logged in users can access this page but if we for example want to do our home page everyone can still access that whether they're logged in or if we just go back here little ways whether they are not logged in so here we have a logged in user and they can access this home page and if we remove that they can still access the home page no problem at all now the next form of authentication I want to handle is going to be for our admin page because we only want admins to access this right now even non logged in users can access the admin page and users such as user - which is not an admin can also access this page so we first need to check if they are a user and then we need to check that they are an admin to authenticate this route so I first want to start by just doing the user authentication because we already have that written so instead of our server we can just say we want to authenticate that we have a user and now this route is only available to logged in users but if we want to authenticate this to a specific role we need to write some code in our basic auth to do that so we're gonna create a function which is called off role and this is going to take in the role that we want to authenticate so inside of here we need to return a middleware which is going to be a request response and next so we can say return a function which takes request response and next and then inside of this function we want to check to see if the role is the correct role so we can say if request user role which if we look in our data we have this role attribute for every user which is going to be equal to one of these different types of rules from inside of here so we want to check if the role is equal to the role that we pass in to our auth role then everything is fine but if it's not equal to that we need to do some code inside of here so we're going to send a status this time it's going to be 401 that essentially means you do not have access you are forbidden you don't have the correct permission and then we can just send down to the user the simple text that just says not allowed otherwise if this check is not the case we can just pass in next here saying that everything succeeded as we expected and of course we can just export that by saying off role down here now instead of our server we can bring that auth role in just like that and instead of our admin we can say we want to authenticate the user and then we want to authenticate the role and in our case we'll bring the role types in so we can say role here this is going to be all of the roles from data right here this admin or basic and we want to check for role dot admin and let me just close this so we can see this full screen and put a comma here so first we wrought indicating our user then we're authenticating that user has a role of admin and if both of those are the true then we run the code inside of here so let's test this out over here we're accessing the admin page with the user no user at all so we click send and it says you need to sign-in okay now we're accessing with a basic user a non admin user we click send and it says not allowed but as soon as we try to access us with an admin user which user one here is our admin user and I click send you're gonna see that it properly returns admin page so now only admins are allowed to access this route and the great thing about this off roll request that we just created here is we can easily change this to be for basic users for example if we wanted this to be basic users only we could do this and now only basic users can access it but of course for this we want only admin users to access it so that's just a really basic way to set up a role authentication for your different routes and this right here is gonna cover most of your authentication needs but when it comes to specific routes such as project route we need to be a little bit more specific because if you remember correctly in our data each user has certain projects that they're linked to so for example Sally only has Sally's project that she can access and Joe can only access Joe's project but Kyle since he is an admin he can access everybody's projects even his own so that's some special code that we need to write in to our projects controller here to make sure that we set up all of that proper authentication this is we're having a really rigorous system around your authentication and permissions is really going to help and I'm going to show you exactly how to do that so let's just close out of this so we have a full screen to work with and what I want to do is create a new folder which is just going to be called permissions and inside of here I want to create a permission for our specific route in our case our projects so let's just create a new file we're gonna call it project J s and instead of here we're going to create all of the different authentications for what we can do with a project so if we go over to our route you can see this route is trying to view a single project so I want to create a function in here that says can view project and this is going to take in a user as well as a project that the user is trying to view and then I want to return true or false for if the user has access to this project so what we can do is just return here user dot roll equals the admin role we want to check if this user is an admin because if that's true they can access every project so let's import that admin role real quick we can say Const role is going to be equal to require we want to just do dot slash dot dot slash and we have data right here thanks is gonna give us our roles so we can say role admin just like that and we want to say or if the user is actually part of that project for example in our data they have that user ID set on the project then they also have access so what we can do is we can say project dot user ID is equal to our user ID so either the user is an admin or they created that project themself then this will return true now let's just make sure that we export that so we can just come in here to say can view project just and now inside of our actual controller we need to set up authentication around that so the first thing that I want to do is authenticate that the user actually exists we never want anyone to access this page unless they're signed in so we want to use that auth user function so we need to bring that in again by just saying Const auth user we're gonna set that equal to our require here which is going to come from dot slash basic auth and then we also want to bring in our authentication for our different permission here for can view project so we can say Const can view project it's going to be equal to require for whoops dot dot slash go into the permissions folder and then go into this project section so this is going to get that function that we just created and now we want to create a new authentication which is going to be forgetting a project so we'll say off get project just like that and we'll create that function down here so we can say function off get project and this is going to be a middleware so it's going to have request/response and a next and now inside of this auth get project we essentially want to use this function we just created and if this is true allow them access otherwise do not allow them access and return that forbidden status so let's jump over here and we can say if request whoops I'm sorry can view project so if they cannot view the project and remember we need to pass in our user as well as our project so we have a request dot user and request dot project this set project function is setting our request dot project for us right here so if we have a project it'll be right here and if not we're gonna get a 404 error anyway and to set this we just pass the project ID inside the parameters here so if we cannot view the project then what we want to do is take the status and we want to send 403 I'm sorry 401 and then we want to here return res dot send not allowed just like that otherwise we just call next now we can finally test this to see if our authentication is working for our project so let's go to slash projects and we're going to pass in an ID for example we'll do project number two so only user two will have access to project two as we can see here user two is linked to project number two so if we come in here and try to send in user three and if we check user three is just a basic user so they don't have access to any of the projects except for their own we click send you see we immediately get not allowed the user does not have access to this project if we pass in user 2 who is the person that created this project and sent we get the project back and if we pass in user whoops I'm sorry user number one this is the admin user here this person should have access to all of the projects so when we click send request here you should see that we're getting this request with the project being returned for our user 1 as well as for our user 2 so this is great that we're able to narrow down exactly which users have access to individual routes based on other conditions other than just their role but we also still have that role based authentication as well now the next thing that I want to work on is going to be our projects route here because this is going to return all of the projects as you can see we have a list of all the projects but user 2 doesn't have access to project 1 or project 3 so we don't want to show project 1 and 3 for user to the admin is going to have access to all of the projects so they should get the full list but the basic users should only get a list of their own individual projects returned so we need to create yet another function inside of our permissions here to handle which actual projects the user has access to view so it's create a simple function called scoped projects and this is just going to take in a user as well as a list of all of the projects that we want to scope down to that individual user so the first thing that I want to check here is if the user dot roll is equal to that roll dot admin then obviously they have access to all of the projects so we're just going to return the list of projects as it gets passed in otherwise if they're not an admin we need to limit this role so we can just say return here for our projects and we want to actually filter these projects to only the projects the user has access to so we're just going to say project user ID is equal to user ID so we're only returning in projects that have the same user ID as the user that is being scoped to unless that user is an admin in which case we return all of the projects so we can come down here and say scoped projects so that we pass that out and now inside of our project controller we'll just come in here and say scoped projects and instead of just returning all of the projects right here what we want to do is say scoped projects for our request user whoops make sure I put this in parentheses properly and then pass in the projects here so essentially we're passing in a list of all of the projects as well as the particular user and scoping that list of projects down to that individual user so if I save this and now test this why pass end user to send a request you can see only the projects of user two are being returned if we go to user three we're getting only users three projects but if we pass in our admin user and send the request you see we get all of the projects being returned so this system is now handling lists as well as permissions for individual routes also you're gonna notice something interesting if we delete this and click send we're probably gonna get an error as you can see we got an error here and that is because we aren't actually authenticating this get route we're letting everyone access it we need to make sure that we use auth user to only let users access this route now if we send this request we're gonna just get an error saying that you need to sign in now to show you how easy this system is to extend I want to create yet another route instead of our projects here for let's say deleting a user so we are deleting a project we can say router dot delete and we want to delete a individual project so we're just going to say project ID we want to call that set project middleware to actually set our project we want to make sure that only users can access this so we're gonna off user here and then we want to just do another auth but this one's gonna be off delete project and then of course we have our request and response which are being returned out and inside of here I'm just gonna send something that says a deleted project since we aren't actually using a database I'm not actually going to delete anything we'll just send out a message so let's create that simple off for deleting so we'll say off delete project and all we want to do is change this from a can of view to can delete project and then essentially if they cannot delete it it's going to send not allowed otherwise it'll continue on to the next and we want to bring that can delete project function in so we'll just import that here which means we need to create this function inside of here so we can come in create the function can delete project which takes a user and a project and this is actually going to be the exact same authentication here we're gonna say admins can delete anything actually let's change it we'll say you can only delete projects you create admins don't have the ability to delete your projects so you can only delete a project that you create so essentially your ID has to be the same as the project user ID and if that's the case then you can delete the project so now let's try to test that out we can just say delete here and we're gonna try doing this for project two we'll send the request and we're gonna get you need to sign in so we can come in here and we can sign in with our user ID and we'll say that we want to try this with user 3 they don't have access to project 2 so we get not allowed if we send in user 2 and we click send you see that it deleted the project because they have access and if we send in our admin user if you remember correctly we said the admin user cannot delete projects so if we click send request you see again we get not allowed because the admin user can only delete their own project so if we try it on project 1 you can say they can delete that because that's their own project and as you can see the system is really easy to extend if we wanted to create a new route for example editing we could just create the new route create a new authentication and create a new permission and that's all we need to do same thing if we want to create an entirely new controller for users for example we can create a new permission for our users and allow different permissions for users to do different things on user objects and the best part about this system is that these functions are not coupled to your actual routes inside of here which means that if we wanted to show or hide a link in our view based on if AV user can view a project or not or whether or not they can delete it or not let's say we have a delete button in our view and we only want to show that delete button to people that can delete the project but we can actually just use this function can we project and we can show or hide that delete button based on the user being able to deleted because this doesn't have anything to do with our actual controller middleware here is completely separate which is really important about this permission system and what makes it so flexible and so useful in so many different scenarios and that's all it takes to create this really flexible user permission system if you enjoyed this video check out my other authentication based videos linked over here and subscribe to the channel for more videos just like this one thank you very much for watching and have a good day
Info
Channel: Web Dev Simplified
Views: 138,925
Rating: 4.9622951 out of 5
Keywords: webdevsimplified, nodejs, node.js, node js, node js tutorial, node js user permission, node js auth, node js user auth, node js user roles, node js user, node js auth roles, node js auth permissions, express auth, express js auth, node js authentication, node js user authentication, express js tutorial, node js express tutorial, node js express, node js express user auth, node js express auth, node js express auth tutorial, node js express uesr permission, js, javascript, auth
Id: jI4K7L-LI58
Channel Id: undefined
Length: 22min 44sec (1364 seconds)
Published: Tue Apr 21 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.