How to Manage User Roles in NextJS / NodeJS

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so recently one of my freelance clients asked me Josh can we Implement role-based authentication into the app that we're building together and I said yes of course we can do that it's a good security practice that makes a lot of sense and while I had done it plenty of times in the past I was never a hundred percent happy with the way I used to implement it so I set out on finding a better way to do it and I found one this is the one I'm gonna share with you in this video I think it's a secure and B easy for beginners to understand so that's what I want to share it with you let's dive right into it and take a look at how to implement it so here is how we are going to implement role-based authentication first off I've got the dev server already running so we can navigate into the browser click the login Tab and before we actually log in I want to show you what happens so let's start up the Prisma Studio I am going to be using Prisma for this you could just use a type or um SQL lives if that's what you wanted to the core feature or the core idea is going to stay the exact same um so we can look into our database that's why I'm using Prisma I think this is a super cool feature we've got access to the account the session and a user and now if we login with any account that's going to create that account in the database now this is totally fine it just created the account we can see that as the user right here it created all the relevant information and then same for the year actual account and based on this we can now Implement our role-based authentication again the the problem is totally unrelated to this this from a different project don't worry about this um so let's say for example we only wanted this page to be accessed by an admin right if we took a look at the current implementation and we go to the dashboard page this is the one we are navigated to then we are always throwing an auth required error but we want this to be in and let me zoom in a bit for you an admin only page where only admins should be able to navigate to this page right here how do we go about implementing this and the first step would be for every user we need to determine their role right what is is this is this user a admin is this user just a regular user and the way we can do that is let's navigate into our Prisma schema like that we currently only see the default options from next auth where we have an account a session a user and then some boilerplate at the start of the file and now before the user let's Implement something called the user role we're going to call this an enum instead of a normal model which will allow us to just select the enum options later which is super handy let's call this a user role and in here we can determine which possible roles there are for users let's just say there's an ad oops an admin row and also there should be and this is not going to become a separator just go on to the next line and there should also be a user role and just like that we have created the rows but we haven't assigned them to any particular user yet and the way we can do that is down here in the user model we can say the role this is a custom property that we're creating together right now is going to be of type user role the enum up here and then we can also set a default value it would always make sense to have the default as a user and obviously not as an admin and when I press Ctrl and spacebar to see which options we have we can already see that an admin and a user is pre-selectable so in my case I'm going to choose the user hit save and then we can push that into our database let's do that in here now to push this at least with Prisma into the database the command will be yarn or npm or I think it's npx Prisma DB push and what that does is it pushes the local changes we have just made in our Prisma file up into the cloud database that we're using in my case that's cockroachdb you could be using mongodb and Planet scale anything else it doesn't matter and then we can say yarn prism or generate because we have now pushed up the data into the database but we still need locally um to have those types to work with typescript and then we also want to restart or typescript server to reflect the changes that we have just done and after that all is done that was super quick by the way we can go into our database once again and take a look and by running yarn Prisma Studio or npx Prisma studio and take a look at the current state of the database and we should be able to see that for every user not for every account let's navigate into the users we can now see there is a role property added right here that we have just created if I go into this and wanted to change it we can already see we have a user option and an admin option I just need to click the admin click save one change and then I change the role of that particular person however if we try to get access to this role in the application right on the page for example we can get rid of the error for now let's try to get access to the session at least with next auth the way you do that is by saying cons session or call this whatever you want it's going to be get server session and in here we want a path past the auth options that we have we can just log this out for now let's log out the session that means whenever I navigate to this page and reload it then the session should be logged out and as you can see the session does not contain any information about the current user role which is a problem right if we just wanted to display the page based on the user role we don't even have access to the role yet so the question is how do we do that and the way we do that is by going into the auth options the options we use to configure um next off in my case that's going to be in the lib folder because I put it there in your case that might as well be in the actual API rod that's common as well if you're using next auth for this then you chances are you have it in the Pages directory under API auth and then next auth to have the code in here I just um offloaded that into the lib folder let's go back in there to my auth.ts and your code should look somewhat similar to this right um and the key that we want to do is whenever we access the session from any page this is what we get access to currently at least it's the user ID the name the email and the image and if I added something else like session.user.i don't know it's going to be equal to hello world we're just going to put in a string there um first off that's going to give us a type error because this is not defined anywhere in the next off type that we're using to do that we're gonna go into our next auth.d.ts or whatever you call the file if you even have a file if you're in JavaScript you won't even get the error if you're in typescript you just might and the session doesn't know what this value is so if we just add it the I don't know of type string then it will stop complaining and now it will know what this value is and interestingly now if we reload the page now we will get actually access to the I don't know property so that's how we put a property into the session obviously we don't want a property that is this useless we want the actual user role and the way we do that is by saying session dot user.roll is going to be equal to and this is going to be equal to the token dot roll because the token the Json web token that we're using to do all of this is going to contain the role because now we are going to put it in there your code again might look different than this but the key takeaway that you should have is and we want to return the role in our Json web token no matter what your code looks like the Json web token should contain the role of the user in my case since we persist that role in the database as I've already shown you I'm fetching the database user at the very beginning for every Json web token that's created and then that allows me to put in the DB user.row that we fetch from the database into the Json web token so it then gets propagated to the session callback in next auth and we can add it to the session so database into the Json web token into the session that's how we do it now again the types are not defined but we know the types the role is of type user row that we get from the Prisma client because at least with Prisma it's super handy if we Define it in our Prisma schema we have access to it as a typescript type and similarly since we're also adding this to the session we want the roll property in here too as a user role we can save all of this we have added the role to the Json web token and to the session meaning if I reload the page now we should get access to the current user role and we do right here as admin so to conditionally check the logic we want to prevent access to the admin only page if the role is not an admin and to do that we can say if session dot user and now we can see the role in here because we just added it if the session user role is on is not equals unlike so and then either admin or user in our case that's going to be admin in that case we want to throw a new error saying you need to be an admin for example period so just like that we turned this into an admin only page and if we reloaded this we are an admin but if I change the role back to user in the database and we refetch this then it says you need to be an admin and we are not allowed to access the page how cool is that so now we know this works securely very intuitively because honestly the only things we've done quick summary is first off we've added the enum user role to our Prisma schema then we have implemented a role property for each user again I've done this in Prisma you can do this and sqlize and type orm in node postgres even whatever orm you use as long as you get the idea of adding a user role and then adding each role to a user and this works just fine specifically with next auth we then added the role types only if you're in typescript right if not you don't even need to bother and then we get access to the role for each Json web token again this is not next auth specific whatever you use for authentication as long as you use Json web tokens um you can store the information in there however you do it it does not matter and then from the Json web token whenever we create a session we read the role value from the JWT put it into a session that we can then retrieve for every page for example we can determine the current session and then check if the session roll property is equal or unequal to admin and then do the rendering um based on that that's how we Implement role-based authentication I thought this was a super cool approach super clean approach to do this it's also easy to understand for beginners if you like the video make sure to leave a like and I'll see you in the next one have a good one and bye bye
Info
Channel: Josh tried coding
Views: 30,923
Rating: undefined out of 5
Keywords: nextjs, nodejs, role based authentication, role based, typescript, typescript tutorial, nextjs 13, nextjs react, next js typescript, nextjs tutorial, nextjs typescript, web development, role based auth, role based access control, express, expressjs, josh tried coding, joshtriedcoding
Id: yCJH72nZ8DI
Channel Id: undefined
Length: 12min 11sec (731 seconds)
Published: Tue Apr 04 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.