Role-based Authentication in NextJs 13 using NextAuth

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we're going to implement role-based authentication using next auth in Nexus 13. we're going to create this application where we have this admin path that only logged in users that actually have the role set to admin on their account can access so if you go back to the home page and try to log in using this Google login that we created we're logged into our account as you can see and now if I try to access my protected pages on the server and or on the client I can access them but if I go ahead and access the admin path it says you're not authorized because if I open up my mongodb where I'm holding my user information as you can see if I refresh this page this user currently has the role set to user so therefore they cannot access this admin path now let's see how we would go about implementing this using next auth now we're going to build on top of the project we built on the previous videos on this channel where we implemented next auth in our next js13 application inside the app router I'm going to include a link in the cart so you can watch that video to understand how we got here in the first place the first video is implementing next auth in a nexjs13 application the second video that you're going to also find it in the card takes us a bit further a bit Advanced we're going to implement an authentication using a middleware and we also provided this account path where they would update their information or their profile using server actions we're going to build on top of where we left off where we have this next.js application as you can see on the left hand side and the last thing that we did was using a middleware this middleware is what comes from the next auth package it was running on our profile page to protect that page and also on this on any path that starts with the protected path and just as a refresher if you haven't seen that video inside the app we had this profile page this is the user dashboard or these protected Pages where we had this client-side page that we were using the use session hook to hook into the session and also the server render page which we use a get server session function from the next auth to actually get the session but because we were running the middleware from down here this is going to tell next.js with this config matches that we want to run this middleware on our profile page and also the project also any path that starts with starts with the protected page to be for the user to be authenticated if they're not authenticated the default Behavior out of this middleware is that they would be redirected back to the signing page where they can just sign in now all I have done now is that I have also added this admin path to this matcher so our auth middleware is also running or protecting our admin page so if the user is not logged in we want to make sure that they cannot access that page now going to the documentation for the role-based access control it's actually not on the next auth JS where you would find next year as a specific documentation it's on the auth js.dev this is the new documentation as you may know next auth is expanding to be auth JS where you can also use it in other libraries like swelt or other Frameworks it's not next.js specific so some of the documentation is still in the old site and some are in the new the robust access control is in the new one I'm going to include the link in the description so you can find it up now here is uh talking about actually implementing or passing in a role uh to our user when we are creating our users by creating this profile callback so the first thing that we would want to do is going to our next config so if I go to app and API auth and next auth route this is where we are initializing how we want to use the next auth package we exported these auth options as a separate object so we can just pass it to get server side sessions on the server side to access the session now on the signing page as you can see here I have this continue with email or the magic link provided like on the form but it's not actually implemented here for the sake of this tutorial we're just going to continue with the Google login but it will be the same concept there too now the first thing is that to actually set a role for our users when we are creating them so you can also pass in this profile callback function to your providers so they can actually set a role now whatever you return from this profile function or callback is going to be used to create your users in your database so if I go back to the database where we actually see the user you can see the user has an ID name email image role mapping to the object that we are returning from here and the profile is what comes back from the Google oauth in this instance it has more properties than what we're extracting here this is what we needed and the results of whatever you're returning from this profile as I mentioned is used to actually create the user inside of the database now as you can see down here also to persist this role on the token on the Json web token and also on this session object on the client side we are using these two callbacks so JWT callback and the session callback generally speaking callbacks index auth or asynchronous functions that would run at specific moments in your authentication float so for example whenever a user creates an account or signed in this JWT callback is called to create or return a token and right after this callback this session callback is called where you can access anything that you set on the token to also add it to the session and whatever you return from this session callback is going to be the session object that you can access on the client side for example inside of this project protected page on the client side where we're using this use session to actually access the session this session object is going to be mapping to whatever you're returning from here excuse me so as you can see here when the user signs in if there's a role on it just as we are setting it here if you're actually persisting that role also on the token and right after this callback we're going to have the session callback where we're reading that rule and also persisting it on the session so if I now go back to my admin page this is the page that I have added on top of what we you can find on the previous video whereby I'm using this get service session function to just check the session if the user has not the role of admin I'm going to say you're not authorized to view this page otherwise I'm just going to go ahead and show them the admin page so now if I go to the admin page as I am logged in but my user as you remember is just having a role of user now if I go ahead and actually update this to have an admin role so even with us updating the database we can't still access this admin page you have to force the user to sign in again if you're updating their role now however you're going to implement this inside your application whether talking directly to your database or having this as an admin feature where you can just change the role of the users you have to force them to sign in again so if I sign out here while I'm at on the admin page it's going to redirect me back to the signing page because our middleware is still protecting this page to be only accessible when the user is authenticated but if we now go ahead and log into our account as you can see this time around I actually can see the content of the admin page and I'm authorized now the downside of the way that I just showed is that you have to force the user to sign in again for the updates to take effect an alternative if you're using a session database or a session strategy where you're holding a session table or a session collection for the logged in users it's first of all easier to log them out of the session so they would be forced or required to sign in again and also inside your session callback you can have this logic of actually reading the session again when you change the role so the implementation may be different from application to application but we now know that first off first of all when we are creating an account inside next auth we can pass in a role with the profile callback function or even if you're not doing it at that time we can still read it from our database pass it to our token and pass it to our session so we can decide whether or not to show a page to a user depending on their role now the next thing that I want to talk about is actually to implement this using the middleware now the other way that you can use the next auth middleware other than exporting the default function that comes out of the next auth is to actually get this with auth middleware and specify some options these are going to be the same options that you pass into your next auth when you're initializing it specifically you can use this authorized callback whereby you you get access to the request object and also the token and if this authorized callback function returns true the user is going to be authorized if it returns false the user won't be authorized to access whatever path that they're trying to access and they will be redirected to the admin page so if you're still matching the admin profile and protected page to instruct next.js that we want this middleware to run on these paths but to differentiate between the two paths that I have I'm checking actually the next URL object on the request to see what's the path name and if the path name is admin meaning that if the user is trying to access the admin page I'm going to check to see if they have a role of admin and I'm going to return true if this is equal to admin which is going to authorize them to access that page and if they're not trying to access the admin path they're going to probably be accessing one of these two path because that's the only time this middleware is going to run in that case I just want to know if they're logged in or not if there is a token inside of your authorized callback it means they're logged in and if there is no token they're not logged in so I'm turning this into a Boolean saying if there's a token return true authorize a user to access the page whatever page they're trying to access if there is no token they're not logged in you can also pass in a middleware function to this function where you can do extra stuff if the user is actually authorized so this middleware is going to only be executed if this authorization callback returns true so you can do extra stuff over here now one downside of implementing this roll base flow with this middleware that I found is that if you have a user that's logged in but it's not an admin it's just a regular user but they would still try to access your admin page this middleware is going to run and it's going to check and see they're trying to access the admin page and it's going to return false because they're not an admin so returning false from this authorized function by default is going to redirect them back to the sign-in page but the user was already signed in so they're going to back go back to the signing page now one way to get around this is to also on the signing page have this logic that looks and see if the user is already logged in and they redirected back to the sign-in page and the Callback URL set on the URL is actually going back to the admin page so have this logic to actually say hey you're not authorized you're logged in but you're not authorized to access the admin page that's the only downside that I found I didn't find any other way to kind of solve this because by default this with auth function returns a middleware and this is going to look at the authorized callback if you return false from this is going to just automatically redirect them back to the signing page if you could come up with a different solution to bypass this problem that I may not have seen let me know down in the comments but other than that that's a wrap for this video we covered role-based authentication using next auth in Nexus 13. if you have any questions hit me up in the comments like always and until next one bye
Info
Channel: Hamed Bahram
Views: 15,645
Rating: undefined out of 5
Keywords:
Id: urZ0iMugiiI
Channel Id: undefined
Length: 13min 28sec (808 seconds)
Published: Sat Sep 09 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.