Protect your NextJs 13 app using Next-Auth

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
the next auth package just released an update that now supports the new Nexus 13 route handlers and in this video we're going to use that to set up authentication in our next JS app we're going to build this simple application together where we would have some protected pages on the server and also the client and also some protected API routes hey friends welcome back to the channel if you're new here my name is Hamid I'm a full stack web developer and here on this channel we talk about modern web dev topics like react.next.js so let's go I've started with a brand new nexjs app by running pnpx create next app with the latest flag and if you're not familiar with that you could just head to your terminal type in pnpx or npx if you prefer npm and then create next app you can add this latest flag to get the latest version there is no longer need to pass in the experimental app flag to this because this command is going to ask you if you want to set up your project with the app directory it is going to also ask you about typescript eslint and recently added Telvin CSS so you can just set up your project right off the bat if it tells yes and that's exactly what I've done here I've set it off with telling CSS I'm going to walk you through how to set up next auth and explain what I've done inside my app folder to create different pages that we need and to protect our routes different pages and API endpoints so let's go to uh the next auth documentation site where we can install next thought I've done this so if you want you can also do this if you're coding along with me here I'm also going to include a link to the source code for the GitHub repository so if you want to peek and see what we have done or the final version of our application you can you can just do that but following the steps inside the getting started section of the next JS documentation we can install the next auth package and then we have to initialize the next auth by adding this catch all API route to our Pages API folder now this is for when we didn't have the new route handlers in the app folder and also when the next auth package didn't support the new route handlers but as you can see here if you're using next.js 13.2 or above inside the app router we can now initialize the config of our next auth inside of our route handlers and that's what we're going to do now if you don't want to use the app directory you can still initialize your next auth config inside of the pages folder I actually have a video on the channel where I'm adding authentication to next.js 13 but I'm using the Pages directory to initialize next auth but in this video we're going to use the route handlers that was introduced in xjs 13.2 which is the equivalent of our API endpoints but inside the app directory to also initialize next auth and if you're not familiar with the route handlers which are your new API endpoints inside the app directory there is a dedicated video on the channel I'll link it somewhere in the card that talks about the new route handlers and how you you need to use them in this video I assume that you have already seen that or you have already you already know how to use the route handlers and we're going to just set up the next auth now following on this guide that they've included the link here in the docs as you can see here the process of initializing the next auth config inside of the app directory is very similar to what we used to do inside the Pages directory where we would Define some options and pass those options to this next auth function we're getting from the package now the only difference inside the app directory is that we are exporting this Handler that's really return from calling this next auth function and passing in or our options to it if you're exporting it as get and as post and this has to do with the new route handlers in xjs 13.2 where you need to export name functions from your routes that will respond to that specific request so if it's a get request or a post request you need to have named functions to handle those requests now this catch all route from next auth is going to create different functions for get and post to this endpoint and handle your authentication with just exporting this function similar to what we were doing in the Pages directory now a side note here that we didn't have to put this new route TS or JS file inside of the API folder that you can see here if I go back to my app you can see I have this API folder created inside of it I have this auth folder inside of it I have this catch all next auth folder and inside of it there is a route.js now inside the app directory you don't have to put it in API folder you could just include this route.js or TS files inside any of these folders I will turn that path into an endpoint the only limitation is that they cannot live at the same level as a page or layout because in that case next to it doesn't know if you're trying to hit the endpoint or if you're trying to get the page itself but to make this easy as it's recommended inside this next auth documentation we are putting it inside the API inside the auth folder and that's exactly the pattern we were doing it in in the Pages directory so we're just doing the same thing so it makes the migration easier so let's go to my route.js file and see what we're doing here now as you can see I have defined some auth options and specifically my providers I'm only going to be using Google provider on the site you can see there is the email kind of option for signing in with magic links or passwordless links I haven't set that up in this video I have a different video on the channel where I talk about different options the strategies and providers in next auth that was index.s 12 on the Pages directory the concepts and providers are exactly the same so you can use that video if you wish to set up a passwordless magic link or email provider for your sign methods you just have to add in a denote mailer package to be able to send the emails you have to have an SMTP server set up to actually send those emails but as I mentioned the I have explained already in that separate video how you can set that up here we're just going to use the Google oauth as a social login because that's easy all you need to do to set this up is to import this Google Provider from next auth providers and we're going to have to pass in the client ID and client secret for this I've created a DOT end dot example here that tells you the stuff you need to be passing into next auth for it to work correctly first one is the next auth secret this is a secret that used to sign Json web tokens the next auth URL is whether you're running it from localhost in this case it is and in production is going to be the domain of your application the client ID and client secret from Google you can get it from your Google console you can go and open up a new project add some API credentials and get the client ID and client secret bring them back here and set them up inside of your dot end dot local so the next auth package can can read them and create this provider for you the other thing that I am passing in is this Pages option to my auth options and I'm saying for the sign in page I want to use this for slash sign in path now if you don't provide any pages to next auth it comes built in with some pages sign in sign out verification and error pages but if you wish to customize any of those pages you could include the path to those pages here so next auth would use these Pages for those specific actions and use the rest if you haven't provided anything now I'm exporting I'm creating this Handler by calling this next auth function passing in my options and I'm exporting this Handler as get and post just as how we saw it inside the documentation now that we have initialized our next auth config let's just go back to the getting started guide and move to the next step the next step is to actually share the session state with our client-side components for that we're going to use this session provider component from next auth which is a context provider and we're going to wrap our components with this session provider now inside of the Pages directory you would do this inside of your custom app component or underscore app file where you could just get the page component and wrap it with this context providers now inside of the app directory we don't have the underscore app but we do have this main root layout that's representing or it's a combination of our underscore app and underscore document.js into Pages directory so let's quickly look at here in the layout this is where we're defining our root layout this is the outermost layout of our app folder which represents the root layout of our whole application if you're not familiar or comfortable with how the structure is inside of the app directory old include a playlist in the card somewhere where I walk through this new concept of layouts and segments and routes to get comfortable with but basically this is our root layout and all of our children page components are going to be plugged in here so what I've done here is I've included a header which is a simple header we're going to look at together there is a footer over here as well and then any page would just be plugged inside of this main tag I'm using the new metadata API again there is a dedicated video for this I have a video for every update that came out from uh the next year's team on the next year's 13 so check the playlist out if you're wondering about this metadata API or the new next font which is very easy to set up in the app directory here as you can see I'm using the inter font now for the provider itself I'm CR I'm using this custom client component that I have here provider so let's see how this looks this is a client component as you can see up top we are instructing xjs with this use client directive because mainly we want to use this session provider which is a context provider using react context so it needs to be a client component that's why for we're using that use client directive up top and what we what I'm doing is that I'm wrapping these children that's passed to this provider component with the session provider that we're getting from next auth so just like how here we would just wrap our page components with this session provider component I'm now wrapping my pages over here so going back to the layout you can see everything that's going to be rendered inside of our app directory is going to be inside of our root layout unless you have different route groups and different root layouts but in this case I only have one root layout and every page is going to be plugged in here so therefore it's going to be inside of this session provider which is a react context provider so therefore any client-side component that needs to get access to the user or to the current session they now can use the use session which uses the use context hook under the hood to get access to the session so now that we have this provider let's actually look at a client-side page that is using that session now as you can see here in my main navigation I have two pages one is a protected page on the server the other one is a protected page on the client so let's go to the app to this protected folder you see there is a client and a server let's start from the client page now as you can see here we are using this use client directive up top to instruct next.js that this is a client-side page mainly because if you're using the use session hook which is a react Hook from the next auth package that allows us to check whether or not the user is logged in now something that you can do with this Hook is to pass in required true option which basically turns this page into a protected page so it requires the user to always have a session for the user to be logged in to be able to see this page and if they're not logged in they're going to be redirected back to the sign-in page from where they can complete the sign-in flow and they'll be then taken back to this page so that's the default Behavior another option that you can pass in here is this unauthenticated uh function that you can pass into the use session which tells next auth what should happen on this page once the user is not logged in and as you can see I'm using this redirect function that I imported from next navigation to redirect the user to the sign in page and I'm also manually setting this callback URL pointing to this protected client route so that they're just redirected back to this protected page once they completed the signing flow now this is supposed to be the default behavior and is the default behavior of the use session Hook Once you pass in this required true option but for some reason it's not working inside the app directory it works but the only thing that it fails to do is to actually set the correct callback URL maybe cannot access the paths inside of the app directory quite yet it redirects back to the home page so it works it protects this page and if you're not logged in it will redirect you back to the sign-in page where you can continue to sign in flow but once the sign-inflow is done it has to bring me back to this protected page it it fails on that part it just brings me back to the home page so to bypass that I'm passing in my own on authenticated function here which just tells next auth what should happen on this page once we have an unauthenticated user I'm just saying redirect them back to the signing Euro and I'm manually setting this callback URL so that I make sure once they completed the signing they're back to the protected page so it'll make more sense if we see this in action so let's go back to our application if I'm trying to access this protected page on the client and I'm not currently signed in I'll be redirected back to the sign-in page as you can see here and the Callback URL is set to protected client so once I go ahead and try to log in with my account I'm back in the protected page on the client side as you see I'm signed in as Hamed and then you can see my avatar up top there indicating that the user is logged in now just to show you what would happen if I do not include this um manual redirection that we did to show you what needs to happen and doesn't quite happen inside of the app router so if I am right now signing out of my account I'm on the home page signed out so if I try to access the product protected page on the client side and redirected back to the sign-in page now as you can see here it did set a callback URL but it is setting it to the home page and not to the protected page so once I go ahead and sign in from here instead of it bringing me back to the protective page it just goes back to the home page and if you wanted to have this extra step or functionality you can just add this unauthenticated function that's a callback you can call so with this if I just sign out if I go back to try to access a protected page on the client side I'll be taken to the sign in page and this callback is now pointing to the protected client from where if I sign in and complete I'll be back to the client-side page so you can add this extra I don't know if this is a bug with the way that the next author is reading the current paths inside of the app router or not but the workaround for now is just to use this manually to redirect them and set this callback URL now as I mentioned once they're logged in or once there is a session the user can actually see this page where I'm just showing their name now before looking at protecting our server render Pages let's actually look at this header component where we're rendering this Avatar and sign in button so if I go back to my app folder inside of this component folder I can see this header component where I'm rendering different links and also this sign in button now this sign in button is a client-side component with the inclusion of this use client directive mainly because we're using this use session hook to check whether or not the user is logged in if they are logged in meaning that there is a session available we're going to show this menu drop down which is built with headless UI which is responsible for rendering this drop down where we show some information about the user and maybe some links to a profile page where they can manage their account or a link to sign out and if there is no session excuse me we're going to show this sign in button which on click is going to call this sign in function from the next auth package and all this function does is that it redirects the user back to the signing page and automatically sets the Callback URL now to just show you what or how we're actually signing out the user inside of this drop down there's two links as I mentioned one takes them to their profile page if it exists and the other one is just a button that on click calls a sign out function from next auth package which just signs the user out now with this out of the way let's actually look at protecting our server render pages so if I go back to the app directory inside of our protected path we can see the server folder and a page.jsx inside of it which is responsible for rendering our server protector page now by default all of the pages layouts and components inside the app directory are going to be react server components unless you indicate their client-side components with the use of this use client directive as we've seen and with react server components first of all you can turn them into async functions and fetch data or call asynchronous functions right inside your page component and secondly they're just going to run on the server these components are not going to be executed or run uh on the client side and no JavaScript is going to be shipped for these pages to the browser to the user to run on the client side now to get the session on the server side we are going to use this new get server session function from the next auth package if I go back to the documentation for this get server session function we see that we can call this function to get the session anywhere on the server side if you're in the Pages directory this may be your get static props or get server-side props function or your API endpoints if you're using the app router or the app directory index.13 this is going to be your server components just like how you're doing it now or inside your route handlers which are again your apis running on the server side and the way that it works if you are using it inside get server side props inside the Pages directory you have to export this author options that you used to initialize your next auth config you have to export those options and actually pass those options together with the request and response to this get server session to get the session on the server side this is an example of using this new function inside get server-side props which is a function that you use to fetch data index.s 12 or inside the Pages directory but for the use in API routes or in the app directory as you can see down here you don't need to pass it the request on response object the request object is going to be sent to this automatically all you need to provide is this auth options that you use to initialize your package so as you can see here I'm using this auth options if I go back to where I initialized my next auth inside the API auth and this route JS I'm exporting this auth options inside of my next auth catch all route so that I can pass this off options to my get server session inside of my react server component as I'm doing it over here again if you're using this get server session inside of the app router you don't need to pass in the request on response object to it just as we had to inside of the Pages directory here you only need to provide the same auth options you use to initialize next auth config with that I would have the session again if I have no session I'm going to use this redirect function from the next navigation to redirect the user back to the sign-in page and I'm manually again setting the Callback URL to protected server this is going to be red with the next auth option so that once the sign in flow is completed the user is going to be redirected back to the protected page in this case the server page so let's test this out actually going back to our application so right now if I go back to the home page I'm logged in if I go to the protected server page I can see this is a server protected page and I'm logged in now if I log out over here it refreshes the page realizes that I am not logged in redirects me back to the sign in page and sets the Callback URL correctly to the protected server so if I go ahead and now log back in here I'm redirected back to the protected page on the server side and I'm logged back in now that we've looked at protecting our Pages whether they're rendered on the server or on the client side let's actually look at protecting our API endpoint so going back to our app directory inside the API I have this hello path and a route JS file inside of it which turns this segment into an API endpoint let's look at this route.js file as you can see if you're exporting a named get function from this file which opens this route or endpoint to a get request and inside of it because this is running on the server we're using this same get server session function from next auth passing the auth options to it if you're checking the session if there is no session we're going to use the next response which is an extension of the response API and it comes with some helper functions such as Json I'm sending a Json message back to say you're not logged in and if there is a session I'm just going going to use that session retrieve the username out of it and send it back as a Json to this endpoint so to test this out let's go to four slash API for slash hello we are right now logged in so because I'm logged in I'm getting my name back if I go back to my application and actually sign out now that I'm signed out if I try to access that same endpoint of API hello we see the message that you're not logged in now as you can see we can use this get server session function anywhere on the server to check whether or not the user is logged in and protect our react server components or server rendered Pages or our API endpoints inside of our route handlers that's enough for this video folks the added authentication to next.js13 using the app router the new route handlers and the next auth package if you looked at protecting our Pages whether they're rendered on the server or on the client we also looked at protecting our API endpoints or route handlers if you have any questions hit me up in the comments and I'll see you in the next one bye
Info
Channel: Hamed Bahram
Views: 72,894
Rating: undefined out of 5
Keywords:
Id: Eh3EpwqT4cM
Channel Id: undefined
Length: 24min 48sec (1488 seconds)
Published: Sun Apr 30 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.