Next-Auth Login | Register in Next.js 14 with MongoDB - Login with Credentials and Github

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi guys welcome back to another awesome next GS 13.5 video in this video I will talk about one of the most demanding topic called authorization and authentication so let me show you what I will be building in this video so this is the login page we can navigate to the registered page login page and dashboard page is actually private it is protected so when I will be login with the different user I'll be able to navigate to this particular route and we can navigate to the Home Route Home Road is the public so let me show you what we have on this login page in the login page we have this form we can log in with the credentials we can log in with the GitHub and the process that I'll be showing you login with GitHub you can follow the same process to login with other providers as well from here we can navigate to the register page and from register page we can register a new user I'll be creating a new API route in next.js 13.5 that will handle the registration and storing the data of users in the mongodb here and once the user is successfully registered along with the proper validations and the data is stored in the mongodb database we can navigate to the login page and here we can log in with the registered user which is stored in the database and I'll show you how we can store the data of the user when we log in with the GitHub as well so I'll be using next auth.js library to implement the login authorization and login with the GitHub so let me show you what we have here by running this small authorization and authentication app so we have this login page if I try to log in with these credentials it will show me this error message and we can modify these error messages as you want we can add loaders we can show the models tool tips but the main focus of this video is the core functionality and the reason it has shown this message because the user with this email ID is not stored in the database you can see it is showing the query result zero all right first of all I need to navigate to the register here I can navigate from here or by clicking on the this register here button okay so the umair2 at admin.com and the password is abcd1234 I can click on register we can add different loaders and it processed that registration for the user and automatically navigate it to this login page okay but first of all let me go to this Atlas and click on this refresh button and see if that user with that email ID is registered or not you can see that it is registered with this ID automatically generated and we have this encrypted password which I have implemented with the code okay using the B Crypt package all right so let's go back and now if I try to log in with this email ID which is registered in the database if I click on it now you can see that I'm successfully able to logged in and we don't have the login register Links at the nav bar we can actually log out by clicking on this button we can navigate to the dashboard page which was previously protected because I was not logged in or authorized with this page okay and we have this email ID with which I have actually successfully logged in and this email ID is actually stored in the database all right so let me navigate two different routes and we can actually log out over here so if I click on this login we can actually log in with the GitHub as well if we have this page let me click on this login with GitHub and I will show you how we can store the data for this particular user which has this email ID which is the email ID for my GitHub account and I'm successfully logged in first time it will show you a pop-up or a model to authorize the GitHub with this application okay I've already authorized that's why it did not show on my system so I'm successfully logged in I can navigate to the dashboard page and even log in with the GitHub this user is also getting stored in the database all right now you can see that it is stored the reason it is not showing the password because when we use any wider we don't provide any password that's why I'm not storing this email ID for this user in the database the reason I'm storing the user details in the database for both GitHub credentials or any other provider which we might want to use because later on if we have other models like the settings profile data analytics that we want to link with the user then user details should be stored in the database then we will be able to make some relationship between different models and I will be creating a long crash course video with the complete blog application maybe you can suggest what kind of app I should be building a production level app in upcoming videos comment below if you have any suggestions okay so this is the whole application I have momodb I have this next auth and this is the small authorization and authentication process that I'll be showing you before moving further and start implementing this small authorization application I just want to request you guys if I go to my channel I will be navigating to my next gs13 tutorial you will see that I've already created more than 30 videos on next year's 13 covering almost all major topics that you would require to become a good next js13 developer so you can check out my playlist or other playlist as well on angular 16 react.js chat GPT JavaScript tutorials so I'm putting a lot of effort creating these videos for you guys it's just a request to you guys to do subscribe my channel and like this video it will really encourage me to create more videos for you guys so let's get started I've opened up a vs code and open up an empty folder so make sure you have latest version of node and npm installed in your system so in the terminal of vs code I'm going to create a new nextges 13.5 project so I'll start off with writing npx create next app at latest I'll hit enter it will ask me few questions so so I will hit enter and it's going to ask me the project name so I will just be giving the next auth or register anything you want so I'll go with the typescript eslint Tailwind CSS yes I'll go with the source folder app router yes and no for import Alias so the project is created now I will start off installing few dependencies that will be required in our app so I will come in the terminal let's go inside the project folder and I will write npm install and first of all I need bcrypt JS for encryption of the password then I need Mongoose then I would need next auth I'll hit enter okay so it's going to install these dependencies after downloading and I'm gonna go inside the package.json file so it has actually installed and given it the latest uh value after each of these dependencies all right so it's actually installing these ones as well so here you can see that it has installed a b crepe Mongoose and the next auth over here all right so let's run this project first npm run Dev is the command that I have run so let's go to the browser and see what we have by default and that should be coming from this page.tsx file so this is a default UI so I'll start on modifying the UI first adding some nav power and create the forms for login and register so let's first modify this page.tsx this file actually executes on the Home Route so I will remove everything within this main element so after I remove these I'm going to add a home page text inside it let's add the H1 and I'm going to write the home page now let's go to the browser and here you can see that it's showing the home page and it's working in fine and this is the Home Route let me close it and I'm going to open up the layout.tsx file and these are all the children that will render all the files and the components that I'll be creating in this app directory if you don't know anything about Nexus 13 check out my playlist next year has 13 tutorials you can learn everything about this technology okay so this is the children and above this I will first wrap it uh within the div just to add some Tailwind styles to it so I will start off by writing class name and inside it I will add Max Auto Max width 5xl and text I will add the 2XL I will be adding the Gap to and mobile will be the 10 okay so this is the div and below this Above This children I'll be creating a new component which I will call a navbar and the navbar will be visible to all the pages that I will be navigating to so first of all for that I will be creating a new folder inside this Source folder and I will name it components inside this components I'll be creating a new file and I'm going to name it navbar dot TSX okay I'm using the vs code extension that I can use rafce and it has automatically created this stuff for me so first of all at the top I will be importing stuff one for link link I will be using to navigate from one route to another route so from next slash link all right and then I will be using the router instead I can only work with the link in this file okay so inside this nav bar I can actually start off creating a UL okay and inside the URL I can create the LI elements so inside it I can start off creating a div and inside this div I can create a link element which I have imported above so first one will be targeting the home page and then inside this link I can have the LI home all right so let's save it so this is the first link that I have created let's first import this navbar component in my layout file so I will start off writing the nav bar it will show me a hint yes so this nav bar is going to be visible to all the components which I will be navigating to so there seems an error so I need to close it actually okay so I have saved it I have saved both of these files so let's navigate to so now you can see that this is the Home Road I can click on it and it is already on this Home Route so our navbar is visible along with this home page component uh element the home page okay so now let's go to the navbot and inside date I will start off uh adding few styles to it so I will be writing Flex I will be writing justify between and then I will be writing the M10 items Center okay so let's save it and let's refresh and you will not see any difference right now so I will be creating new divs under it so this div is going to contain all the navbar elements on the right side at the top okay so I will just copy pasting this stuff inside it so this one is actually referring to the dashboard so first of all I'll be writing the dashboard here and I can change it over here this will not be navigating to it will show 404 because I have not created any file for this particular route as of now okay so this is the dashboard I can create uh more links for it so I can have dashboard and then I can have the login and then I can have the sign up okay and this I can call anything I can call it register or anything I want so let's save it now let's go and let's refresh and now you can see that there is a justify between and there is a space in between over here all right and to add some space and make it look nicer I can go on this div and I can add a class name and I can add the flex Gap 10. okay so let's save it now you will see that it's looking like this and it's looking fine and there is a space around it as well and if I click on any of these you will see there will be a 404 because these are the files which I have not yet created I'll be coming to this file again because I'll be implementing the logic of the sign in sign out and when I'm authenticated I want to hide these couple of links and I want to show the email ID and the logout button which I'll be coming back to this navbar file all right so first of all I need to create these three components that will be referring to the three routes so inside this app folder I'll be creating a folder and the first one I'll be giving it a register make sure the name of this folder should be matching uh with this one this uh route href value over here which we have added the sign up okay so I can actually change the route stuff the register over here so that it can Target the same folder name and after that I can create the page.tsx and rafce it's going to create a page and I can change its name to register okay let's copy paste over here so it has been created now let's create another folder and I can name it login and inside the login let's create the page.tsx file RAF CE and I can change uh the text over here so let's create another folder not file I'm going to create a folder name dashboard and it will be having a file page.tsx rafce and then the dashboard all right so let's save all of these files and let's go let's first try to refresh and now I'm at the Home Route I can navigate to the dashboard I can navigate to the login register so this is the content visible so our routing system is working fine and we are good to go so now I want to implement the register functionality first including the validations of the form and also the data storage for the user in the mongodb okay so I'm going to open up the page.tsx file within this register route and inside this div I'll start off designing the form first of all okay so this is the dev I'm going to create another div inside it and inside this tab I'll start off writing the H1 and inside this H1 I can add the register heading okay and in the first div I will be adding the class name and I'll start off writing the flex I assume that you have a little bit understanding on the designing this tutorial is not specifically on the Tailwind CSS so I'll just copy pasting few of the designs you can learn Tailwind separately if you want and I have a plan to create a separate video for the Tailwind as well and for the second div I will add a class name and for this I will add another styles for the second div and this is for the heading and within this div below this H1 I also want to add the class name to this register text as well I want to make this registered text a little bit bigger so I've added this Tailwind style So Below H1 I will start off creating a form element okay and this form element is going to contain the input and it's going to be having the type of the text first of all and then we can have a class name which I will be modifying just now and then we can have a placeholder email and I'll be giving it a required field okay so for the class name let's add the class name to it like this these are the Tailwind classes which I have added and I'll just be copy pasting it for the password so this is for the text and for the password I can actually change the type to password and it will handle the validations by default to some extent and placeholder would be the password as well and then we have the required field and we are pretty much done with this as well okay and below this I will be adding a button and button will be of type submit and then I have this class name and I want to add some styles to this button as well so I'll be writing this styles for the tailment all right so let's save it let's go to the browser and see what we have all right so it's looking so great we don't have the desktop button but the overall form is looking good all right so let's add the text for the buttons so I have actually added this thing so I will be adding the register text and close it with the button all right so it's looking great and below this I want to add some error handling which I will not be doing just now uh but uh I want to add a link to the login page so we can actually navigate to the login page directly from the register page as well so below this form I'll be creating an other link so I can add a link to it and inside this link I can have the login with an existing account okay so this is added so let's save it there seems an error which I think I have to import at the top so so let's import that and there should not be any error now and it should be giving an error for the href which I need to provide to navigate to the login page so let's add the href all right so this is going to navigate to the login page and also I want to add some class to it for the styling so now let's go and now you can see that login with an existing account is looking fine all right so Above This I also want to add this or as well okay so now you can see that login with an existing account is working fine I can navigate to the login page from here and I can navigate to the register page so over design process for the register form is pretty much complete now I want to configure mongodb in my project so that when we add a new user email and password over here click on the register button the new data for this user should be added in the mongodb okay so first of all you need to go to this cloud.mobodb.com and sign up with your account any email ID you can use and after that you need to go to this projects folder projects route and I will be clicking on the new project and here I can name any project to it so I can write next 13 and I can write the mongodb okay and I can click on the next uh leave it like this I'll be clicking on the create project from here all right so once it's getting created it will be navigated to another page and here we will be creating a new cluster so I'll be clicking on this button and here I can actually select any package so we don't need any paid account for this video I'll be clicking on this free and we can select any provider for the cloud uh I'll leave it like this I can click on the create okay so I'm going with the default settings for it so now I need to set the username and the password so here I can set the username and then I can set any password to it and I can click on the create user but before that I need to copy paste uh this password to somewhere because I'll be needing this password in our project configuration file so I'll just be copying it and then I will be pasting it in my project so I'll clicking on the create user so it will be created with that username and the password all right so below this I can actually allow my IP to access this database so it's actually already added by default so now if we want to allow any other IP we can go to this network access and add any other IP and we also want to make this database public so whoever wants to access it can actually access it from all over the world so this IP is already accessed on my network so I'll click on the finish and close so congratulations on setting up the access rules uh go to the overview and after this I will be having this connect button I can click on this connect button and I can click on this driver and I can actually copy paste this URL but before that I've already copied the password which I need to save somewhere and let me save it somewhere here and now I can actually copy this stuff over here okay this URL all right which I will be needing and after this this is pretty much it we need to do here and click on the close and now we are already in that particular next 13 mongodb and after that we can click on the database and here we can actually check all the collections by clicking on this browse collection button but before that let's go to the project and configure our project to connect our project with the mongodb which we have just configured so here I'm gonna open up this file I'm going to click on it I'm going to create a new file and I'm going to create a new EnV file dot e and V here okay so in this file I'll be creating and copy pasting that URL which I have just copied and I can name it URL underscore URL equals to and I will be pasting that URL which I have just copied okay and then I will be replacing this password field with the password which I copied previously make sure you also copied that one and after that we want to give the name of the database which we want so before this question mark I'll be giving any name to it so I can name auth uh next okay this is the name of database you can name anything in real world project you will would like to name the project of like a blog app or e-commerce app or something representing your brand okay so that's pretty much it we need to do in this file for now until we don't uh work with the next auth so let's close it now and I'm going to create a new folder within this Source folder so I'm going to name it let's add the utils folder here okay and I'm going to create a new file and I'm going to name it dp.js all right so in this file I'm going to import Mongoose which we installed at the start of this video so I will be importing Mongoose okay and then I will be creating the const connect function async and we don't need anything from here and here first of all I'll be writing Mongoose dot connections 0 dot ready state if it is already connected we don't want to make a connection again with the database because whenever we will be making a connection or call an API we will be needing the connection to the database so this is must when we are trying to implement it in next.js application okay and after that let's add the try catch and I'll be using a weight Mongoose connect is the built-in function and in this one I can actually write that variable name which I just created this complete URL will be required to connect to that database okay so I'll be pasting the name of that URL and it will give us an object and I'll be just copy pasting few uh formalities uh you can say uh if these are actually required so use new URL parser for parsing the data and unified topology is added over here and also let's add the catch here as well for the error okay and I'll be throwing a new error so error connecting to the Mongoose or anything you want to add inside it so once that will be done I can actually log that out so connection uh is done connections successfully established or anything you want to add over here and after that I can actually export it from here so export default connect all right so it you can actually ignore that this is just the passing error so I'll just be ignoring this so let me go through it again so we have Mongoose connection ready State true yes that's fine and we are actually connecting with that URL which we just copied and it is true we are this this thing okay so let's close it now I'm going to create a new API in my next.js so I'll be creating uh an API folder in my app directory and inside API folder I'll be creating the API route which I want to create so I will be creating a new folder and I will be naming it a register make sure that this register is referring to the API not the actual front-end route because I'm inside the API folder okay so inside this register I will be actually creating this route dot TS okay so inside this route.ts I will be handling the user registration process uh but before that I need to create a mongoose model for that so I will be come over here and I'll be creating a new folder and in this folder I will be naming it models if you don't know how to create Mongoose model I've already created a complete crash course on nodexpress mongodb that consists of 42 videos you can check that out to understand completely about the Mongoose node and express so in this model I'll be naming it user dot JS okay and in this file we actually need to import the Mongoose and from the Mongoose I need to create the schema for that all right and for creating the schema we need to use this schema it is actually a class which provide us this object and inside it we can create different objects uh for one for the email other one is the password so email type string obviously email would be of type string unique means that we want it to be unique so no two users can have the similar email ID it is required password is a string and it is not required because we will be storing the data of the user who is getting logged in using the GitHub okay and while login with the GitHub we don't have the password so that's why here I have added the required field for the password as empty we can add the separate validation on the front end whether the password is given when login with the credentials email and the password all right time spent will be automatically adding when it was created when it was updated will be automatically added over here and once that is added I will be adding the default and first of all I need to check if it is already uh existing so Mongoose model or I can use the Mongoose model and then I can name this model user all right and then I can give the name of user schema variable which I have created above so that's pretty much it we need to do in this model file for the Mongoose and I think we are good with it let's close it now we need to work with this backend API which we want to create so here first of all I will be uh creating and importing few stuff first of all I need to import that user model which I have just created and it should be coming from that utils folder it's not showing over here so let's try to add that so let's add this and we have the utils and then we have uh the we have to have the models okay models and then we have this user all right and after that we want to import the connect function which we are exporting from the db.js file which we have just created so it should be coming from that folder it's not showing here as well so I will be manually writing add and then we have this utils and then we have this DB file all right so I also want to import the B creep which I installed at the start of this video from the B crypt.js file and this is to encrypt the password before storing it in the database all right and then I since I'm using the typescript I can actually import the next response from the next server all right so sign up require the post request because we want to pass the data from the front end so I will be creating a post request for that so post equals to the async and then I will be creating a request any Arrow function and let's close it all right so first of all let's get the data which is coming from the front end using the request object uh for this function and I can get that and destructure it using the email and the password which will be coming from the front end so I can write the await request.json all right and after that I can actually connect with the database okay so now what I want to do first uh I want to return the default response so first of all I can add the try and then I will be adding the catch block here so inside that draw I will be saving the user after validating and that will be stored in the database okay and in the catch block I can return the new next response error and I can pass the status as well if I want to so the status will be 500 because this is an error okay and we can give any type to it like this any all right so after this let's try to check if the user with this email ID is already exist in the database or not if it's already existing then we will not allow it to be created again because email ID is unique so I will be writing the cost existing user equals to the await user dot find one and then I can actually write the email I will be checking with the email if it exists and I will be checking if existing user is true means that the email ID is already existing in the database then we will be still be returning the error message next response and I can actually return the email is already in use okay and then we can actually pass the status 400. okay let's close it like this all right and if it is not true then we will proceed further and after that I can hash the password so hashed password uh like this and I can write the await B Crypt dot hash is the function and I will be passing the password and I can add the complexity with the number up to five times and then I will be constructing a new object for the new user equals to uh new user which is the model Mongoose model which we have just created and I'll be passing an object email email and then the password will be equals to the hashed password and then I will be coming inside this try block and I will be writing this await new user dot save it will be saved and then I can return a success response user is registered all right and then I can pass the status 200. okay so there seems an error let's add the curly braces so let's save this file so I think we are done with this file and we don't need to add any other validations so we are done by creating this API actually okay now I'm going to go to this page.tsx file which is the front-end URL for the register and this is the form and in this form I will be creating an own submit event handler and using that event handler I'll be calling this API will which will be on the route localhost column 3000 slash register which is the name of that folder okay and it will be stored in the database for that in this form let's add an on submit so on submit and handle submit which I have yet to create const handle [Music] submit function which I have created and it's going to be an async function e of type any and then the arrow function all right and E is to prevent default to pre and the default behavior of it let's write the preventive font like this and then I will be fetching the email and the E dot Target dot value but the target will be giving us two values so I can get the value from here and then I can write the password from the second index all right so let's first add and log this out uh email and the password is being fetched successfully or not so in the terminal there seems an error for the client component so actually next year is 13 whenever we are using the hooks or any events like The Enclave con submit we have to convert the component into the client component so at the top I'll simply writing the use client within the double quotes and after saving the files you will see in the terminal that the error is gone now I'll be going to the browser and let's refresh first and I'll be simply clicking on this register button and let's go to the console window and verify so we have this email ID and password is getting printed so it means that we are successfully being fetched uh fetching the email and the password and I'm using the console ninja extension and it's also directly showing the output of the console hole over here as well so let's remove this up and first of all I will be validating the email and the password and for validating the email I'll be using the string test function and I'll be creating a separate function above this function so this is valid email it will be receiving an email so this is the regex which you can understand it is a separate different topic and it will be calling the test function and this test function is going to be given with the email and if the email is successfully validated it will return true otherwise it will return false okay so I can write if is valid email if it is not valid then I will simply be return empty so it will not be processed again okay and then if this is not getting triggered if email is valid then I'll be checking the password as well so password if the password is invalid or the password dot length is less than 8 we are just validating it so length is less than 8. okay and if it is true then again we are going to return this thing okay this is just for validation that I am doing and uh after this I also want to set an error below this form over here so if there is some kind of error over here I want to set and show the red color error that invalid email or uh invalid password stuff like that so I'll be creating a state variable within this component so I can write error and then I can write the set error equals to use state from the react and it is going to receive an empty string and for navigation let's also try to add the router as well which will be coming from the use router from the next slash navigation okay so this is the function actually so now uh let's add the space and below this I will be calling an API which I have just created over here route dot DS okay so in this file I will be writing a try catch first so in this try I will be receiving the response a weight I'll be using the built-in function Fetch and I'll be writing the API slash register is the name of that folder within the API folder and this is an API okay since it is a post request and I will be passing the data inside it so I'll be giving it a method and method is the post and after this I can actually pass the headers as the Json because email and password will be passed as the Json data okay so content type colon uh equals to application slash Json [Music] okay so it should be the headers actually so content type Json and then I'll be writing the body Json Dot stringify and inside it I'll be passing an email and then the password which is being passed from the form below okay so once that is done I will be having uh it's throwing an error because I have not added this catch block yet so let's add the error here and like this and now the error is gone okay so now once I will receive the response I'll check if the response dot status is equals to 400 then I will set the error to this email is already registered okay we know that we have created this API and we are returning the statuses from here so if email is already registered we are returning the status 400 if email is successfully uh user is successfully registered we are setting the status 200 so this is what we are using over here okay and now I can write if the response dot status equals to 200 then I will simply set error to an empty string and I will be navigate to the login page because we are successfully registered all right and if there is an error let me copy this set error and we can anything error error and the try again and we can log this as well for our understanding and help okay so let's save it and at the top we can set the error message over here as well just like we have added over here so set error uh before returning if there is an error we can add different validations if the email is invalid we can write the email is invalid and if the password is not valid we can write the password is invalid okay so let's save it and below this I can actually show this error message as a string so I'm going to come down and below this button we can actually show the error within this form and for that I can write this one this is a P tag and if the error exists then it will show the P tag otherwise it will not show so let's save it now and it should work fine now so we have written pretty much a lot of code and I'm just going to refresh the page and currently if I go to the browse collection I am just verifying if there is no user already existing so there is no user let's refresh uh yes there is no user currently added over here so I'm gonna go here and I can click on this register okay so there is an error internal server error all right so this is where the error is showing Mongoose dot model so let's open up that model file user.js and it is actually only model not the models okay so let's save it now let's try again uh let's go to the browser let's refresh and I'm going to click on the register now so let's see what happens so if it is successful and yes we are navigated to the login page the reason it took a lot of time because first it was uh establishing the connection with the mongodb so we can see that connection successfully established which is being printed from this log and the API is working fine as well and the reason I'm telling this because we are successfully navigating to the login route because the status is 200 now in order to verify we need to go to the this one let's refresh this and it should be working fine all right so this is the name of database and this is the user successfully registered with the encrypted password along with the created ad and updated ad field so over registration process is complete using next.js 13.5 along with the mongodb now before working on the next auth for login I want to test the validations which I've just added let's first try to register with the same user so I'm clicking on the register now you can see that email is already registered it's working fine let's add the invalid email over here so let's click on register invalid email let's change the password like this so it's showing only one error because the we have handled it like this all right so validation is working fine now it's time to go ahead and integrate the next auth for the login with the credentials and login with GitHub now I'll be using the next auth.js in order to integrate the login functionality using credentials and the GitHub provider and the cool thing about this toolkit is that if we go to the providers we are given with a lot of these providers using which we can enable the login functionality and I'll be showing you how we can do it with the GitHub but the code level implementation is pretty much same with all the providers whichever you want to use okay so we have the Google we have the Instagram login LinkedIn and GitHub gitlab email Dropbox and all these providers okay first of all we need to install next auth which we have already installed in our project and then if we go down we first need to create this file next auth.js within the square brackets and before that we need to add dot dot dot and let's create this file and add up this particular piece of code so first of all I need to create a folder So within the API directory I'll be creating an auth folder let's see auth and then next auth so I'll be creating so it's also showing the that if you are using the version 13.2 or above we can check out this guide this is for the lower versions and I already know that what is written in the guide so I'll just be showing you so I'll be writing auth and inside it I'll be writing next auth okay this is the folder I'm not writing dot JS after that as it is showing over here instead I'll be creating a new file inside it route dot TS since we are using the typescript all right make sure you write it and spell it just like this which I have written so inside it I actually need to add these providers okay so I will just be writing it like this just copy it and paste it like this so it's giving few errors because we are using typescript which I'll just be fixing in front of you first of all let's go at the top we need that we need GitHub provider and along with the GitHub provider we need credentials Provider from this URL next auth providers credentials and we are using typescript we will also be needing uh these types account and the user as auth user which I've given the Alias name to this user and then we will be needing the uh this one let's say the bcrypt user connect because we will be connecting to database to validate if the credentials which we are logging in is actually registered in the database or not we don't need bcrypt here okay and we'll be needing this user to actually uh create a new user using the login with GitHub okay so after that we are actually using the next auth we can write any data type to this next uh auth options and after that we can add different providers currently it is GitHub provider and above that we can add the credentials provider which we have added above and it will contain different objects inside it all right so after that we have this GitHub provider and GitHub provider actually need the client ID client secret which I'll just be showing you how we can create that to resolve this error we can write question mark and empty string after that and we can write question mark and empty string after that and the credentials for our provider is actually throwing an error so let's fix this error first of all we need to give it an ID so I'll be writing the credentials and then I'll be writing a name with the capital c okay and then I will be giving it a credentials object okay and it is going to take an email and I'm going to give it the email label email and then I need to provide it type and then the text okay and just like the email we also needs to add a password so password label password and the text would be the password as well okay so this is the password text would be the password All rights and the next property is the authorized because we want to authorize it with the credentials which we will be providing okay so I will be writing the async authorize function and it's going to be given up with credentials of type any we can give a proper data type to it uh so this one in this authorize in this credentials we are given with the data that we will be writing in the form of login page okay we can get that from this credentials in the authorize we can actually uh return something from here okay so first of all I can write a weight connect we can connect to the database and then we can process our logic we can create a new user we can check if the user is already existing in the database or not and if it is not registered we want it to be not to logged in automatically we want to throw an error that user is not already registered okay so I can write the try and then the catch with an error and this cache error is going to throw an error let's add this statement and inside this Troy we can check if the cost user equals to the await user dot find one we can pass an object with an email ID and with passing the credentials.email okay and if the user exists means that we are we can log in actually using the credentials then I am going to check if the password is validated or not that is stored in the database and we can do that is password correct equals to await B Crypt dot compare compare and inside it I can write the credentials.password and then the user.password okay so which is stored in the database all right make sure yes we needed the B grip actually so be Crypt uh like this B Crypt from uh B crypt.js okay so now if the password is correct then we are navigating and returning something so I will be if the password is correct then we are actually simply return these things and everything will be handled by it automatically uh and let's add the data type to it like this alt right so I think we are pretty much done with this stuff and we this provider will be running when we are login with the credentials and we actually need to create it to actually enable the GitHub login stuff which we have not done yet which I'll be adding in the environment file because I'm fetching it from the EnV file GitHub ID and the GitHub secret but first of all I need to verify the credentials provider if it's working fine or not for that I first need to go to the login route and build up the form for the login page but first of all I want to create the session provider so that when we are logged in we are able to access if the session for that logged in user actually exists or not next thought automatically handles the session uh for that we need to add few configurations so in this utils folder I'm going to create a new file and I'm going to name it session provider dot TSX okay so inside it I will first change it to use client and after that I will be importing the react from the react and then I will be needing to import the session Provider from next auth react okay so session provider from next auth react all right so after that I will be exporting an auth Provider from here so I can name anything to it so auth provider equals to it will be receiving all the children uh and we are actually enabling all the children to have access to this session variable so that in any component in any route we can check uh if the user is logged in or not okay so I'm actually returning the session Provider by adding the children within it okay and then I'm writing the export default and then auth provider which I have created above all right so once we are done with it we need to go to this layout file and we need to wrap everything within this session provider so that over navbar including the children can have access to the whole session which we are actually using all right so first of all I'm going to go at the top and I need to import that session so first of all I'll be importing the get server session get server session uh is actually required if we have the server component and in that server component if we want to check if the user is logged in or not for that reason we need this get server session okay and after that uh we need the session provider which we have just created so I'll be writing the session Provider from that particular folder which is in the utils folder currently it's not showing that so I don't know why it's not showing so session provider which is coming from the at utils and then we have the session provider okay so I'll come down and first of all I'll be creating a variable for that get server session uh so session equals to a weight e get server session and I will wrap everything within the that session provider so it is await so I'll change it to the async function the root layout okay so outside this div I will wrap it with the session provider and I'll be passing the session for the get server session okay and I will move everything the whole stuff within this session provider now all of our routes all of our components will have access to that session uh so let's save it and that's pretty much it we need to do in the layout file I believe okay so we have the nav bar automatically added we have this uh by default added we have this so let's close it now I want to go to the login page and I want to build up the form for that login page okay and for building up that form I'll be using the same kind of layout for the register page uh so I'll just be copy pasting few of the stuff to save some of our time so I'll just be copying this whole div okay so let's go over here let's try to paste this div like this and we don't have the handle submit we have this register let me change the title of it to login and then we have this text email we have this password we have this button and we can change it to the sign in from register and below this we have this error which we have yet to create and then below this we want to add the login with GitHub button and then we want to add the sign in with actual credentials which which is actually needs to be created okay so first of all let's comment this line we don't have the error and let's remove this whole stuff first of all okay and outside this form first of all I want to add the login with GitHub button okay so let's add that actually we needed that maybe so we have this one so I can add the register and we can have this text register here okay and we can import this link from the next navigation uh let's import this at the top so I will be adding the link from next slash navigation and it should not be destructured like this okay so this has been added there should not be any error over here uh and the reason it's showing uh this error jsx element link does not have the construct called Signature so why is it throwing this error so actually next link here okay like this all right so now we need to implement the login with that credential so we have this sign in button and this sign in button is going to uh call this handle submit button so let's create that handle submit button just like we added in our register and I'm gonna go over here and I'm just going to copy everything from here let's add this so I have oh I have repeated that let's remove it [Music] okay I only want to copy this handle submit actually okay so here I've just pasted that and I will be adding the use router and then the error State as well just like I added in my register page so I'll be writing the Quick Fix from the react use State and the use router should be from the navigation next navigation Okay so we have this validation here as well so I'll just copy pasting from the register page validation so email validation is added and then we have the handle submit let's try to see what we have here we need these lines we are validating the email and we can actually validate the password as well let's keep that and we have we don't need this this complete thing is useless uh and I'll just be removing everything from here and I'll just be showing you we are given with the built-in sign in sign out functions provided by the next auth and for that I can actually import that at the top from the next auth slash react and it is given with the sign in and the use session and the use session hook actually gives us this session variable and this session variable uh give us some data give us some status that if the user is authenticated or not and based upon this variable we can show some kind of logic we can show the loader we can show the error message or we can navigate from this page to another page if we want this page to be authenticated or unauthenticated okay so let me show you how we can uh do this okay so here first of all I'll be using this sign in function below this after these validations so for sign in function I'll be writing const res a weight and I can write the sign in function which is coming from uh this I don't need the sign from crypto I need this function okay here so it is provided with the credentials we can provide anything to it any provider to it can be GitHub Google Facebook Instagram I'm giving the credentials provider inside it and this name is the ID which I have added over here let me show you this one ID okay so inside it I will be first redirecting it to the false I want to manually redirect I don't want it to be automatically redirect so some route okay so I will be giving it an email and the password okay so after this I can validate with the error message so uh we can write if there is an error in login invalid email or password and this error can be returned from that uh this validation which we are returning over here so this is where we are throwing an error okay and we are uh checking if the user exists uh then we are actually returning something okay so invalid and then here we are checking if the response.url property exists we are navigating to the dashboard page if the so if we are successfully logged in means the response will have the URL property exists inside it and it will have some value as well and if we are logged in successfully we will be navigating to the dashboard page automatically otherwise we are uh we are just setting the error because of this okay so I can actually uncomment this it will show an error and let's see what we have here so uh we have this session and we can use this session to automatically navigate to the dashboard page as well using the use effect route okay so I can write the use effect and I can write it like this and inside it I can use the session Dot status equals to I can write authenticated okay and if the session status is authenticated I can use the router replace and then I can navigate to the dashboard the reason I'm writing this because user might want to manually change the route when a user is on the login page then it should automatically be navigate to the dashboard page we don't want user to navigate to the login page if user is already authenticated user first have to sign out to navigate to the login page okay so here this is why we are doing and then we can add the dependencies as well if the session is changed or if the router is changed okay and we can import this as well from the react all right so I think it will work fine let's save it let's see if there are any error over here so we have this use State let's rerun the project so that it rebuilds some some kind of stuff so we have to add the use client at the top since we are using the event handlers so I'll be writing the use client at the top okay so now error is gone it is compiled successfully now let's go to the browser and log in with the user which we are actually registered in the database so it is showing some kind of errors in the console window and we need to First go in the code and let's see what's wrong with this file route.ts within the next auth so I'm going to go down and everything working uh fine here there is no error uh all right so we actually need to export this auth option from inside it otherwise it will not work so export const Handler equals to and I can use the next auth which I imported here okay and inside this next auth I can pass these options which I have created okay and along with that I also want to export the Handler okay so Handler as get and Handler as post Handler as put since we only need the get and post so we don't need to add the put or delete request so I'll just be saving these now let's go and let's refresh and now you can see there is no error in the console window this registered uh user is already registered let me re-verify this thing and I'll be using the same email ID to log in with the user umair2 which is registered okay so I'm gonna go over here let's navigate to the login page and I'm going to click on the sign in button so login is successful we are successfully navigated to the dashboard page and we can see this dashboard text over here all right and we also need to make this dashboard protected so when we are not logged in but before that once we are logged in we want to change these Links at the nav bar so I'm going to open up the navbar file in the components and first of all I will be importing few stuff so I'll start off importing with the session and I also need to import the sign out function from that next auth slash react okay and along with the session I can use use session hook as well so below this I can use the const and I can write the data session equals to use session okay and I can give the data type of any to it you can create the type for that I've already created a video on the typescript for the react and next.js you can watch that video uh if you want to learn about the typing and creating interfaces and classes and stuff okay so first of all this is where we are showing the dashboard login and the register okay so for the login and register I want to check if the session exists session if it exists then I want to show up uh if the session does not exist then I want to show up these two links okay and I need to put these inside these okay and after that I can have another parentheses and inside these parentheses I can check if the session dot user dot email exists but first of all let's add so inside 8 I will be writing An Li element and above that I can also show the email for the logged in user so session dot user dot email so this is how we can get the email for the logged in user and then we can have the button for sign out all right so button and it can have a log out text inside it so let's save it uh there should not be any error in the console so there seems an error what's wrong with it so I think we need to restart the server but first of all let's add some kind of button styling to it so I'll be giving it a glass and I'll be writing some Tailwind styles to it for the log out and also for this button I will also be adding the on click event and to this event I'll be calling this function and I will be writing the sign out function which is being imported above from the next auth slash react all right let's restart the project and see if we still see these errors and ready in three seconds yes let's go uh react context on your server component all right so we need to change it to use client component so let's go to the browser and let's go to the login page and let's try to log in again with the user I'm clicking on the sign in button so let's see what happens it's actually should be uh connecting to the database and yes you can see that it was establishing a connection with the mongodb database first time so now we have this dashboard we have this email for the logged in user and we have this logout button all right so we have this dashboard first of all let's go to the dashboard page and I want this page uh to be only redirected when we are logged in and for that again we can use uh the session but this assume that this component this route is a server component okay we don't want to make it the client component for that reason we can not use this use session and this is the reason we added this stuff in the layout file get server session okay so we can import it from here so I'll be writing import get server session from next auth okay so once that is done I can also import for the redirection so redirect from next slash navigation okay so inside this uh dashboard component I can check if the session exists from get server session because it is a server component if the session does not exist then I will be redirecting it to the Home Route simply okay or the login route or anything you want and let's try to add the class to it as well so that our text is at the center so before actually go to the browser and test this out uh in the terminal you can see that it's showing some kind of stuff that warning next auth URL so we need to add some URLs over here in the dot EnV file and these URLs are not specific to the GitHub provider but it is required when we are using the next auth so in this file I will be creating few variables so that should be the next auth underscore URL equals to http colon localhost colon 3000 okay and after this we need to add next auth secret so next auth underscore secret equals to and we can write anything inside it like ABCD one two three four make sure you add some complex stuff inside it so when we change the EnV file we need to restart the project and there should not be such error in our terminal after writing this okay so I hope that it's working fine let's close this up now let's go to the browser and see what we have so here uh I'm gonna go to the login page again we are running yes we are running let's refresh this page and in the terminal we don't have those errors now so I'm going to login again here so it's waiting because it's establishing the connection yes it's established and here you can see that we are successfully navigated to the dashboard page and we can navigate to the other routes now if I log out it should navigate to the Home Road but it's not it has navigated to the dashboard let's see and we have this validation all right so this get server session is actually require an async of weight so I'll be writing an await keyword over here so let's save it now let's go and now you can see that it has navigated to the Home Route if I click on the dashboard you will see that I'm not able to navigate to the dashboard because I'm logged out let's login again let's click on the sign in and I'm logged in again and now I'm able to navigate to the dashboard route from here because I'm logged in we have the email ID let's log out and now it has navigated back to the home page I'm now I'm not able to navigate to the dashboard page now all right so now it's time to implement the login with GitHub I'll be adding the button over here and I need to add some configuration to it so for that if we go to our route.ds file you know that we added this client ID client secret which we need to create in our GitHub and add it in over dot EnV file so on your GitHub account you need to go to the settings of your profile I'll click on the settings and below this you need to click on this developer setting and in the developer setting you need to click on this oauth apps and you need to click on new oauth app and here we can name anything to it so let's add the next js13 auth okay and inside did we need to add the home page URL uh we need to update it if we will be deploying our application but currently we are running it on localhost 3000 so we can select over here it is optional we don't need to add that and now as next JS provide us a callback URL which we need to provide to it so this is the URL we need to give it to it let me zoom in so you can see this out so localhost 3000 slash API slash hot slash callback slash GitHub so this is required you need to add it and also when you will be deploying your app you will be needing to update the authorization callback URL over here all right so I'll click register application okay so once it is registered this is the client ID first of all let me copy this client ID and let's go in the project I'm gonna open up that dot EnV file and this EnV file first of all I'll be creating few variables okay so first of all it should be the GitHub ID make sure you match it with this GitHub ID yes and I'll be pasting this one next one is GitHub secret all right so GitHub secret equals to which we need to create and over here uh it gives us this button generate a new client secret I'll click on it so here I have this secret showing up you can create yours because after this video I'll be deleting all my secrets and IDs so I'm gonna go to this and I'm going to paste over here all right so that's it for this file I'm just going to close this and inside it we have this GitHub ID and GitHub secret we don't need to do anything for this provider now it's time to go to the login page and I'm going to add a new button for login with GitHub and for this I'm going to come here and above this or text I will be creating a button over here okay so let's create a new button for that I'm going to write a button and it is going to be taking up the class names and also it's going to take up the on click uh since it is a client component uh yes it is a client component and inside it I will be writing an arrow function and they're inside the curly braces I'll be giving it a sign in and inside the sign in I need to provide it a provider which is a GitHub okay so let's add the text after that so close the button sign in with GitHub okay so I hope this that we have already the sign in button which we are using over here here we provided the credentials provider now here we have actually provided the GitHub provider all right so let me add some classes to it so that it looks good so I'm going to add the class name so let's save it let's go and now you can see that we have this cool looking sign in with GitHub and uh let's login with it let's click on it sign in with GitHub and here it is asking me to authorize my application let's authorize and here you are being author redirected okay so we are successfully being redirected automatically to the dashboard page we can navigate to the Home Route dashboard page and this is the email ID for for the GitHub account I'm using and we can actually log out but currently you can see that if I navigate over here click on the refresh uh we can see that we don't have that particular user not added in our mongodb okay so this is what we need to do now because it is required when we later on need to make a complete application for the relationship of different models in Mongoose okay so let's log out and for that we will be modifying this route.tx file and if I show you uh the next auth documentation it gives us these callback functions which we can use callback for sign in callback for redirect callback for session changes callback for JWT so I'll be using the sign in and using this account I hope this account provide us the key provider and we can add an if condition that if the provider is GitHub then we can perform the logic and connect to the database and we can create a new user in the database using the GitHub login functionality so let's open up the route.ts file and below this array for this provider we can have the callbacks so I can actually write the callbacks here okay and it gives us this object so inside this callback I can start off writing an async and there's a sign in callback and uh it gives us user it gives us a count and few more stuff if we go over here so we can see that profile email credentials but we don't need that for now so let's add the type to it since we are choosing the typescript so I'll be writing user and I can give the auth user I added these types over here for the user and this is for the account okay so account and then this is for the account all right so this callback uh gives us a function this is a function and I can check if account dot provider equals to credentials then I'm simply going to return true okay because we have to return true after the completion of this sign in process and after this we can check if the account dot provider equals to GitHub then we can perform the logic and storing the data in the database okay so for that first I will be connecting it to the database and then I'm going to write the try catch because I'm using async await whenever we use async await this is the way we handle the errors so I can start off writing uh error message error saving user or we can also show the error as well and also we'll be returning something returning false if there is an error otherwise if there is no error we can first check uh if the existing user with the email ID is not already exist okay then we will be storing the data in the database so I'll be writing the existing user equals to the await user dot find one which I've already imported above all these stuff this is the user model from the Mongoose model okay so I can write the find one with the email user dot email and I can check if the existing user does not exist means that we can save it in the database so let's add the const new user equals to new user and then the object and then the email user dot email okay and we have constructed this now we can use the await new user dot save and then return true okay and we also need to return true here as well uh if the user exists or not in both the cases we have to return something otherwise there will be no redirection after that all right so let's save it now and it should be working fine now let's go to the browser let's refresh every stuff we are actually logged in let's log out and let's click on the login and we have everything working well let's click on the sign in with GitHub and it should be working fine and we are actually signed in let's go to the mongodb let's refresh and uh here it should be having here you can see that it has actually created this data email ID there is no password because we are not passing the password over here uh we don't have access to the password so if we log this data out user account even the other properties as well we will be given with all the different properties for the GitHub that we can use the links URLs repositories all the followers in our account and all these stuff so we are successfully able to create new user and storing it in the database okay so we can check all the different validations and navigation from one page to another page dashboard is protected because we are not logged in let's try to add a new user Omar 3 at admin let's register it yes it is registered now let's go and verify if it's working fine let's refresh and it should be created over here uh yes Omar 3 at admin.com and password is also added the encrypted password and there will be a validations as well sign in password is invalid now uh we have this email ID that is used to log in with the GitHub if I try to log in with that particular email ID of abct1234 uh let's click on sign in you will see that we can modify this error but I'm not able to log in with this because this email ID exists in the database but the passwords does not exist because this email ID is used with the sign in with GitHub so we can modify different validations I hope that you can add if else condition at different Logics how we can perform all these stuff this is a Kickstarter project for the authorization and authentication that we can work with to build a large application in next JS 13.5 or later versions using the next auth but there is one issue that I want to show you over here which I just want to fix that if we are logged in let's let's refresh and let's login and we are logged in actually we are at the dashboard and we can navigate to the dashboard we have this email ID which is stored in the database now if I manually go to the login route you will see that for one second it will show me the login form and then it navigates back to the dashboard page and if I go to the registered page manually and you will see that it is showing the nav bar as we are logged in but still it is showing this register form over here this is what I want to fix now so first of all I want to fix that login flicker so if I navigate manually to the login page even after login successfully it shows the login form for one second so I've already created a video on how to protect routes in next.js in four different ways you can check that out the recent video in my next yes 13 tutorial playlist in my channel alright so for fixing this one second flicker what I'm gonna do is I'm going to modify this code a little bit uh so first of all use session gives us different properties not just the session so I'm going to comment this line and I'm going to add it again so first of all it gives us the data and I'm going to add its type session and then it gives us a status which is I can give the session status okay and it is from the use session again which we are already using okay so now rather than actually using the status from the session we can directly use the session status over here and we can use the session status over here as well all right so let's save it now I'm going to come over here and add the condition over here uh and we can add the session status is not equals to [Music] authenticated and all right so let's save it and during that one second I also want to add the loader over here so we can have the loading value within this session status as well so I can write the session status equals to and it gives us the loading so if it is a loading I can actually return something inside it so I can write the H1 and I can write the loading dot dot dot okay so let's save it now and let's go to the browser and let's refresh and if I manually navigate to the login route now let's see what happens so it's showing the loading and navigate it to the dashboard page so we have avoided the flickering of the login form using this awesome technique now let's add this condition on the register route as well so I'm going to open up the page.tsx for the register so I'm gonna go and copy the stuff from here so I need this use effect and I need above use session variable so I'm going to paste it over here and we don't have the use session from the next auth we have to import the use effect from the react all right and also we will be importing this loading as well so I will come down and here I will be adding this stuff okay and also I need to add the condition for this div the return statement just like this so I'll be adding this one so I'll just paste it over here let's save it and I hope that it will work fine just like the login route so let's refresh I'm already logged in and I can actually navigate to the register Page hit enter so it's showing loading and now it has navigated to the dashboard route so it's working fine let's navigate and uh yeah and also on the nav bar we should avoid showing the login and the registered links as well uh for even one second if we are logged in and for that case we can also add different kinds of loaders at different condition it depends upon the designs and the UI of your application all right so I think I pretty much covered each and every concept of authorization and authentication in next.js 13.5 and I've explained you how we can use the mogodb to store the data for the users how we can use the next art.js package to implement the authentication using the credentials provider and also the GitHub providers so if you have liked this video do subscribe my channel and like the video as well and comment below if you have any question I'm planning to create a long production level video in next year's 13.5 I'll be waiting for your suggestions in the comment of this video I'll readily appreciate if you subscribe my channel because I'm putting a lot of effort building these videos for you guys thank you so much for watching guys see you in the next video
Info
Channel: Programming with Umair
Views: 12,402
Rating: undefined out of 5
Keywords: next-auth next js 13, next js route protection, next-auth credentials, next-auth credentials register, next-auth credentials sign up, next-auth mongodb, next js, next auth, next js 13, next-auth github provider, next-auth tutorial, nextjs 13.5, next.js 13 apis authentication, protect routes in next.js 13, login register in next-auth, login register in next.js 13.5, for validation in next.js 13, nextjs mongoose connection, next.js 13.5 tutorial
Id: 1SjqRn_Ira4
Channel Id: undefined
Length: 93min 2sec (5582 seconds)
Published: Wed Oct 04 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.