Next.js 13 Authentication: Custom Email/Password with NextAuth.js & MongoDB

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Thank you

👍︎︎ 1 👤︎︎ u/Omkar_K45 📅︎︎ Aug 02 2023 🗫︎ replies
Captions
hi everybody Welcome to GT coding in this video I'll show you how to add authentication to your next app using next auth and we're going to use credentials provider in next auth so that we can use username and password for registration and login and to store the data we're going to use mongodb alright first of all let me show you the demo of the application that we're going to build so here we have this login page and if I click on this link over here for registration here we have the registration page and then we have the link of the login page over here okay you can go ahead and log into your account so for example if I just add some data and if I just add a password and if I click on login we can see that it says invalid credentials because we don't have this data in our database so let's go ahead and create a new user so let's go to register and let's go ahead and add the details so I'll just type John and let's add the email ID over here and now if I just click on register we can see that it says all fields are required and let's add a password over here so I just add a simple password and let's click on register and now we can see that the registration has been completed now here if I open the mongodb database here if I just refresh this page here we can see that we have the details displayed over here we have John gmail.com and we have the name displayed over here and the password is hashed and we also have the timestamps over here so now let's go back and let's log into our account so let's type John gmail.com and let's add the password and let's click on login and now we can say that we are logged into our app and we have the name and the email ID displayed over here and we also have the log out button but now if we go over here to the URL and if I just go to the home page we can say that we have taken back to this dashboard page and if I open register we are taken back to the dashboard so let's log out and if we go to this address bar and if I just type dashboard now we can see that we have taken back to this login page so our routes are protected right now let's go to the register page and let's add a new user so I'll just tap Sarah and now here if you just type the same email ID that we had earlier and if I click on register we can say that it says user already exists so we need to add a new email ID so just change it and let's click on register and now the user has been registered so let's go back to mongodb and let's go ahead and refresh this and now we have the second user displayed over here but now let's go back and let's login and now we can see that we are logged into this new account and we can log out so this is basically the app that we're going to build in this video let's get started right here I have created this folder called auth app and I just opened it with vs code now let's go ahead and create a new Next app so for that you have to go over here to view and click on Terminal and here let's type npx create next app at latest and for creating it in the current directory I'll just type dot over here and let's press enter and here we have to answer some of these questions so for typescript I'll just select no and yes for eslint and yes for Tailwind CSS and no for the source directory and yes for the app router and I'll just keep the default import alias and here we can see that our next app has been created so let's open this so for that you can just type npm run Dev and here we have our app opened in this URL so let's open this and here is our next app and this is the default page of a new next.js application so let's go back and let's go ahead and modify it so let's go to the app directory and let's go to the page file so here we have this code and this design is basically from this code right here so let's go ahead and delete all of this and for now I'll just create a div and I'll just type hello over here and now we can see it says hello let's also remove the default styling so let's go to the global.css file and I'll just remove all this CSS over here I'll just keep these three lines of code for teren CSS and now we can see that we have this home page without any Styles now first of all let's create the UI of our application and then we will add the next auth so let's go ahead and go to the page.js file and I'll just change this to page.jsx now we can simply delete the import of the image from here and I'll just create a component for the login form so here we can see we have this login form so let's go ahead and create a component and I'll just add the component inside a main tag so we'll just name the component login form so let's go back to the root of our application and let's create a new folder and let's name it components and in this we'll create a new file called login form Dot jsx and here let's tap export default function login form LS return a simple div I'll just type login form and let's go back to the page.jsx file and let's import it over here so I'll just type login form and it is auto imported from components login form so now if you go back to our web page here we can see it says login form right now let's start with the design of our login page so let's go to the login form component and let's go ahead and add some classes over here so I'll stop class name and we will use Telvin CSS to style this so let's set the display to grid and we'll tap Place items to the center and let's set the height to 100 report height and now we can see that the login form is in the center right now let's create another division inside this and in this we will add the actual login form so let's create a div and this the first thing we need to do is create this heading so let's create an H1 and let's tap enter the details so now here we can see we have the heading right now let's go ahead and add some classes to this division so I'll start class name first of all let's set a shadow of large and let's also set the padding to five let's set it to rounded for rounded corners and let's add a border top of four and for the Border color let's type green 400 right now let's add some styles to this H1 so I'll just type class name and let's set the text size to Excel and let's set the font to bold and we will add a margin bottom and top of four right now let's create a form and we can just remove the action now in the form we need to add input Fields so let's create an input field and let's set the type to text and let's add a placeholder and let's set it to email and let's duplicate this and for the second one let's set the type to password and for placeholder I'll just type password and now let's go to the form and let's add some classes over here so I'll just have class name and let's set the display to flex and the flex direction to column and let's add a gap of three now we have multiple input Fields so let's go ahead and add the classes of the input fields to the global.css file so let's open the global.css file and here let's type input and to add Tailwind CSS classes you can type at apply and here we can add the Tailwind CSS classes so let's set the width to 400 pixels and let's add a border and let's set the Border color to Gray 200 and let's also add a padding top and bottom to two and let's set the padding left and right to 6. and let's set the background color to zinc 100 and let's give it an opacity of 40. right now let's go back to the login form and let's also add a button so let's stop button and in this button we will type login and let's add some classes to the button so I'll stop class name and let's set the BG to Green 600 and let's set the text color to white and let's set the font to bold and we set the cursor to pointer and let's also set a padding left and right of six and padding top and bottom of two right now the next thing we need to have is the error message so let's go outside this button and let's create a div and here I'll just add some error message and for this let's add some classes so I'll just stop class name and let's set the background color to Red 500 and let's say the text color to white and we will set the width to fit content and let's say the text size to small and I will set the padding top and bottom of one and padding left and right of three and let's set it to rounded medium and let's also add a margin top of two right now we need to add a link to the register page let's go outside this div and let's create a link element so you can just type link and you can just import it from next link so here we have link imported from next Link in this link we need to add an href and I'll just set it to a page called register and here let's type don't have an account and let's add a span and in here I'll just type register and for this pan let's type class name and I'll just set it to underline and let's add some classes to the link so here for the link I'll just have class name let's say the text size to small and let's set a margin top of three and we'll just text align it to the right so that's basically it with the login page now let's design the register page so let's go to our file browser and inside the app folder let's create a new folder called register and in this we need to create a new file called page.jsx and here let's type export default function register and for now let's just return register and if we go back to the login form here we can see that for this link We have set the href to register so now if I click on this register link here we can see we have taken to the register page so let's go ahead and start with the design of the register page so even for the register page we'll create a component so let's go to the components folder and let's create a new file called register form Dot jsx and here let's type export default function register form and let's return a div register form and let's go back to the registered page and here we'll just import this component so here instead of this I'll just type register form and let's import it from components register form now the register form is almost the same as the login form so let's go to the login form and let's copy some of this code so just copy everything over here and I will just make some changes in the register form so let's go over here and I just paste it over here and here we have this error link is not defined so let's import it so just tap import link from next link and here in the heading I'll just type register and let's go back to the login form and here and let's change this to login let's go back and here in this register form first of all we need to add the name so let's duplicate this and here in the placeholder let's type full name so we have the full name email and password and instead of login we need to type register so here in this button let's type register and then for the link here we'll just type already have an account and here I'll just type login and in the hrf I'll just type the link of the home page so with that our register form is complete so if I click on this login link we are taken to the login page and if I click on register we are taken to the register page right now let's design the dashboard so let's go back to the file browser and in the app folder let's create a new folder called dashboard and in this we'll create a new file called page.jsx and here let's type export default function dashboard and we'll create a component for the user info and I'll just call it user info and let's create the component so let's go to the components folder and let's create a new file called user info Dot jsx and here let's tap export default function user info and let's return a div and now let's open the dashboard link over here so let's start forward slash dashboard right now let's import the user info in the dashboard so here let's type import user info from components user info right now let's go ahead and start designing it now for the container division let's type class name and let's set the display to grid and we will type Place items to the center and let's set the height to 100 viewport height but now let's create a division inside this and for this let's add some class names so let's tap Shadow and let's set it to large let's set the padding to 8 and we will set the background color to zinc 300 with an opacity of 10. and let's set the display to flex and Flex direction to column and we will add a gap of 2 and we'll add margin top and bottom of 6. right now let's add the content so first of all let's create a div and we have the name and for the value of the name let's create a span and here let's add the name and for this I'll just set a class name and let's set the font to bold right now let's copy this and paste it down here and this is the email and here I'll just type the email ID but now we need to add the button so let's create a button and in this we need to type log out and let's add some class names over here let's set the background color to Red 500 and text to White let's set the font to bold and let's set a padding left and right of six and padding top and bottom of two and let's also add a margin top of three all right so that's it with the design of the dashboard and with that we have completed designing all the pages of our app now let's go ahead and start with the functionality so for that we need to install some packages so let's open the terminal and I'll just stop the server for now so let's press Ctrl C I wanted to install some packages so let's type npm I and first of all let's install next auth and then we need to install a package called the Mongoose to connect with our mongodb database and then we'll also install a package called bcrypt.js now this package will be useful for hashing our password so let's press enter alright so all the packages have been installed so if you go back to the package.json file here we can see that we have the packages displayed we have decrypt.js Mongoose and next auth right now let's run our app so I'll just type npm run Dev all right so let's go to the register page and we'll write the functionality of register first so here we have the register page so let's go to the register form component now here what we need to do is we need to create States for storing the details so here we have these three input fields we have the name email and password and we need to store it inside the state so that we can send it to the API now for using States we need to convert this component into a client component so for that you have to go over here to the top and the other type use client but now here let's type const and we'll just name it name and we'll have a function called set name and here let's tap use State and we'll just import it from react and the default value will be blank let's create State for the email as well so let's type email set email equals use state blank and let's do the same for password and also error now here we can scroll down and here in this error message we can add all of this inside a conditional so here let's type curly braces and let's add all of this inside the curly braces and here let's type error Ampersand Ampersand and let's add all of this inside parenthesis so now this code will run only if we have any error so for example if I just type user exists now we can see that the error message is being displayed now here instead of typing error message I'll just change this to the actual error message so let's tap color braces error and now we can see it says user exists over here so let's go ahead and delete this right now what we need to do is when we make changes to this input field we need to store the values over here so here in this name input field let's add an on change and here let's type e and let's create an arrow function and let's tap set name and here we need to set the name to e dot Target dot value now what this will do is it will store whatever value you have inside this input field into this state I'll just go ahead and console.logit over here so let's tap name name and let's open the console and here let's add some name and now we can see it says Zone over here because we added the name over here so whatever we type over here will be added to the state right now let's go ahead and do the same for the other input Fields so here we have email so let's tap on change and let's call it e and let's tap set email and let's set it to e.target dot value and let's do the same for the password so let's tap on change e set password e.target dot value right now we need to create a function to handle the submission so here in the form let's type on submit and here we'll create a function called handle submit and let's create the function over here so I'll just tap const handle submit now the first thing we need to do over here is to prevent the default Behavior which is the refresh of the page so right now if I click on this submit button the page refreshes so we need to stop that so let's type e over here and here we need to type e dot prevent default and now if I click on this submit button the page doesn't reload right now let's go ahead and add an if condition and let's check whether any of these values is missing so let's type exclamation name or exclamation email or exclamation password so if any of these values is missing then let's set the error and let's set the error to all fields are necessary and then we'll just return from this function and now let's go ahead and click on this register button and now we can see it says all fields are necessary all right now the next thing we need to do is we need to send the data from these input fields to the API so let's go ahead and create the API so let's go to the file browser and let's go to the app folder now in this we need to create a folder called API and in here we will add all the API routes so here in this API folder let's create a new folder called register and then you need to create a file called route.js so for the apis you need to create this file called route.js and for all the other Pages you need to create this file called page.jsx all right first of all let's check whether everything is working so we'll just create a simple API to display all the details that was sent so we need to create a function so I'll just tap export and we need to create it as an async function and this is going to be a post method so we need to name it post and here we'll get the request so I'll just call it Rec right now here let's create a try catch block and here in the try blog I just first of all restructure all the data from the wreck so just type const and we'll get the details as name email and password and I will just get it from rec.json now this will return us a promise so we need to type a weight over here and if everything is successful we need to return a next response so let's start next response and we'll just import it from next server and we need to type dot Json and here we'll just pass a message so this type message and let's say to user registered and let's also pass a status code so I'll stop status and let's set it to 201 right now here in the cache let's go ahead and return the next response dot Json and here let's type message and error occurred while registering the user and here let's pass a status code and let's set it to 500 now just for testing whether everything is working all right let's go ahead and console.log it over here in the server so I'll just type console.log name and let's type name and let's do the same for the email and the password right now let's go back to the register form component and here let's create a tricast block and here let's go ahead and perform a flex call to this API route so let's tap await Fetch and the API route is API forward slash register and then we need to pass some options so let's set the method to post and let's set headers and let's set it to content type application Json and then we need to pass the body so in the body we need to pass it as Json so let's type Json Dot stringify and here let's pass the name email and password which we get from these input fields which you are storing it inside these states so let's type name email password right now we are getting this error because we are using this await inside a non-async function so here in this handle submit function let's change it into an async function right now let's store this result inside a constant so I'll just have const res equals await Fetch and here let's check whether the response is okay so let's tap if res dot ok then we will just go ahead and reset this form so let's create a const and let's name it form and let's set it equal to e dot Target which will Target the form and here let's type form dot reset and here let's add an else and let's type console.log user registration failed and here in the cache let's go ahead and console.log and I'll just type error during registration and here I'll just pass the error right now let's see whether this works so let's open the terminal and we're going to get the console.log over here because we are adding it inside this route so here we need to get the name email and password in the server so here let's add some details I just type John John gmail.com and let's add a password I just have one two three one two three and let's click on register and here we can see that the form has reset and we also have the details displayed in the server so the API is working all right now let's go ahead and write the code to add the data to our database so we are using mongodb so let's go ahead and create a new project in mongodb right here I have logged into my mongodb Atlas so you can just search for mongodb Atlas and create a new account if you don't have and just log into the account and here you have to create a new project so let's go ahead and click on new project and I'll just call it credentials app and let's click on next and let's click on create project and let's click on build a database and let's select the free version and let's keep all these options as it is and let's click on create and here for the username I'll just set it to GT coding and let's copy this password from here and let's store it inside our project so let's go to our vs code and you need to create a file called dot EnV in the root of our application so let's create a new file and let's call Dot EnV and here we can add our secret code so for now I just paste the password over here and let's go back and let's click on create user and let's scroll down and here for the IP address I'll just set it to 0.0.0.0 forward slash zero and let's click on ADD entry now this will allow us to connect to this database from anywhere so let's go ahead and click on finish and close and let's click on go to databases right so here we have our database so let's click on connect and let's get the connection string so let's click on mongodb for vs code and let's copy this connection string from here so let's click on this copy button and let's create a new environment variable over here and let's call it DB URI and let's paste the code over here and here instead of password we need to add this password right here so let's cut it from here and let's paste the password over here and then at the end we also need to add the name of the database so I'll just call it auth app and let's save this now when you make changes to the environment variable it is recommended to restart the server so I'll just open the terminal and let's close the server and let's restart it so I'll just type npm run Dev right now let's also add this dot EnV file to our git ignore here we have this git ignore file and right now we just have this dot envy.local file added over here so let's also add dot EnV now when we add a file name over here inside git ignore this file won't be pushed to our git repository so make sure to add this to your git ignore file right now let's close this right now let's write the code to connect to our mongodb database so let's go to the root of our application and let's create a new folder called lib and in that we'll create a new file called mongodb dot Js and here let's write the code to connect to our mongodb so let's go ahead and import mongoose from Mongoose and let's tap export const and I'll just call the function connect mongodb and it is going to be an async function now in this let's add a tricast block and here in the try let's go ahead and type of it Mongoose dot connect and you need to add the connection string so we have stored it inside the dot Envy file so for that the other type process dot EnV and we have named it mongodb underscore URI and let's also console.log and let's type connected to mongodb and here in the catch let's go ahead and type console.log error connecting to mongodb and let's also pass the error over here right now the next thing we need to do is we need to create a schema for the user data so for that let's go to the root of our project and let's create a new folder called models and in that we'll create a new file and let's call it user.js and here we will write the code to create the schema so let's type import Mongoose from mongoose and let's type const and I'll just call it user schema and let's create a new schema and let's import it from mongoose now here you can create the structure of your data so let's type name and the name is gonna be a type of string and it is required so let's type required and let's set it to true and then we need to have the email so let's tap email and it is also a type of string and for this also let's type required true and then we have the password and let's set it to type string and required true I will also store the timestamps so let's go ahead and type timestamps and let's set it to true so this will store the time and the date of when the data was added and also updated right now let's go ahead and type const and I'll just call it user equals let's tap mongoose dot model and here let's type user and the schema is called user schema so let's type user schema over here and if you already have this model then we'll just pass the model over here so I'll just type models and let's import it from mongoose so here we have models and let's type dot user so let's add an order over here so if you already have the model then we'll just return the user and if you don't have then we'll just create a new model called user with this user schema right now let's go ahead and Export this user so let's type export default user right now that we are done with the user schema let's go ahead and continue with our route.js file so here we are simply displaying these details so I'll just delete these lines of code and let's write the code to connect to our database and also store the data to our database so let's go ahead and type awit connect mongodb and let's import it from lib mongodb and then we need to type awit user and let's import this from Models user dot create and if you need to pass these details so here let's type name email and password now this line of code will store the data to our database but we don't want to store this password as it is we need to Hash it first so let's go ahead and import from bcrypt Js and here let's create a const called hashed password and let's set it equal to await bcrypt dot hash and you need to pass the string that we need to Hash which is password and then let's add a number for how many rounds of hashing it will do so we'll just pass 10 over here and now we need to store this hashed password instead of this password so here let's type colon hashed password right now let's see whether this works so let's go back and right now we can see that if we click on browse collections we don't have any data in our database so let's go to our application and let's register a new user so I'll just type John John gmail.com and let's type one two three one two three for the password and let's click on register and here we can see that our form is reset so I think the data has been stored so let's go back to our terminal and let's see whether we have any errors so we just have connected the mongodb displayed over here and let's go back to our mongodb and let's refresh this page and here we can see we have auth app in that we have users and we have the user that we just registered displayed over here we have the name email and the hashed password and we also have the timestamps of created and updated right now the next thing we will do is we will prevent the user from creating another account with the same email ID so right now if I just add the same email ID over here and register it will be registered because we don't have any conditions added over here so let's go back to our code and let's create a new API route for that so let's go to API and let's create a new folder called user exists and in that we'll create a new file called route.js and here let's create export async function and the function should have the post method so let's type post and I'll just call the request req and let's create a tricast block now here what we need to do is we need to check whether we have some data with the same email ID so first of all let's connect to the database I'll just tap await connect mongodb and let's import it from lib mongodb and then let's restructure the email so I'll stop const email from await rec.json so we're going to send the email to this API route right now let's go ahead and type of it user and let's import user from Models user and let's type dot find one and here we need to pass the email ID so let's type email now here we will not fetch all the details we'll just fetch the ID so I'll just type dot select and here let's type underscore ID because in mongodb it is called underscore ID so here we can see underscore ID so I'll just select the ID so that we don't need to get the whole data over here and I'll also just type console.log just to see whether we are getting the data so I'll just call this data user so let's stop const user equals await user and here let's type user user right now let's go ahead and return next response and let's import it from next server dot Json and he will just pass the user that we get from the database and here I'll just console.log the error right now let's go back to our register form component and here inside this tricast block let's go ahead and type const res equals await and let's tap Fetch and let's perform a fetch call to this user exists API route so let's type API user exists and let's pass the details so here let's type method and let's set it to post and let's type headers and let's set it to content type application Json and then let's pass the body and let's type Json Dot stringify and we just need to pass the email right now this this structure the user that we get from this route so we are passing this user back to the client so let's go ahead and destructure it so just tab const user equals a weight and let's tab rest dot Json so we are getting the rest from this API call and now we need to add an if condition over here so let's tap if user so if the user exists then I'll just type set error will set the error to user already exists and if we scroll up here we can see that we are setting the error over here in this state now let's go ahead and return so if the user exists then we'll just return from this function now here it is showing this error because we have the same name over here for this constants so I'll just call this res user exists and let's copy the same thing and let's paste it over here all right so what we are basically doing over here is that first of all we are checking whether any of these values is unavailable and if any one of them is missing then we'll just set the error message to all fields are necessary and then we are checking whether the user exists with this API user exists and if you find the user valued to be anything other than null then we are just setting the error to user already exists and then we are just returning from the function and then at last we are just calling API register and we are passing the data and here we are just storing the data to our database so let's go ahead and test it out so let's go back to our web page and first of all let's click on register without filling in any of these details and we can see that all fields are necessary so let's add some details and we will add the same email ID so I'll just stop John gmail.com and let's add a password and let's click on register and now we can see it says user already exists so now let's add a completely new data so let's type Amy and let's add an email ID and let's add some password and let's click on register and now we can see that the user has been registered so if you go back to our mongodb database and if you refresh this page and if you scroll down we can see that we have two query results and if we scroll down here we have the second data that we just added so that's basically how you can store the data from this form to your mongodb database now let's go ahead and redirect to the login page once the registration has been completed so let's go back to our code and here after the form reset we'll just go ahead and redirect to the login page which is basically the home page so for that we need to use use router so let's type import use router from next navigation so here instead of router we need to type next navigation but now let's scroll down and let's type const router equals and we need to type use router right now let's scroll down and here after the form reset let's type router dot push and let's go to the home page so let's start forward slash right now let's see whether this works so let's go back and let's add a new data so let's type robot and let's add the email ID and let's add a password and let's click on register and we can say after registration it is redirected to this login page and let's go back to the mongodb database and let's refresh this page and let's see whether the data has been added let's scroll down and here we have three fields and we have the latest data added over here all right so that's basically it with the registration of our application now let's start with the functionality of our login page and for that we're going to use next auth for the authentication so let's go back to our code now we have already installed the package called next auth so if you go to the package.json file here we can see we have installed next auth so let's go ahead and go to the API folder and in that you need to create a new folder and it should be called auth and in that we need to create one more folder now this is going to be a catch all route so we need to add it inside square brackets and you need to type dot dot dot next auth and the internet we need to create a file called route.js now make sure to have the same names for these folders and files or it won't work right now the first thing we need to do is we need to import next auth so let's type import next auth from next or next and we're going to use credential providers so that we can use email ID and password for the login so we need to import that as well so let's type import credentials Provider from next auth providers forward slash credentials right now we need to create some auth options so let's create a const and let's name it auth options and this is going to be an object and in that we need to have providers so let's type providers and this is going to be an array and in that we can add all the providers that we are using right now we are just using this credentials provider so let's tap credentials provider and then we need to add some options so here let's type name and let's just name it credentials we have to use this name when we use the sign in function and then we need to have the credentials so let's type credentials and here we need to add the details of the input Fields so here we can add the input field for the email ID we need to add the type and also for the password but since we are using a custom login page we'll just leave these credentials object blank right now we need to use a function called authorize so let's type async authorize and in that we will get the credentials so I'll just type credentials over here now here we need to write the logic for the login but for now we just create a user over here and I'll just return that so that we can test it so I'll just create a user and let's set it to a simple object I'll just type ID equals one and nominator return this user so let's type return user now with this the login will work even if we enter the wrong password and email but we are just doing it to test it so let's go ahead and continue with our code and I think we need to import credentials without these colored braces over here right now let's scroll down and the next thing we need to do is type session and here we need to add the strategies so I'll just type strategy and I will just set it to JWT which is Json web tokens and then we need to add a secret so let's type secret and let's add the secret inside our environment variables so let's scroll down and let's go to the dot EnV file and here let's create an environment variable called Next auth Secret now you need to add a random string so I'll just add something over here and the next thing we need to add is the next auth URL so let's tap next auth URL and we need to set it to the URL of our website so if you go back to our page here we can see that the URL is localhost 3001 so let's copy this and let's paste it over here all right I'll just restart the server and let's go back to the rod.js file and let's continue with the code so here in the secret we need to type process dot EnV dot next odd secret which we added in the EnV file so let's tap next auth Secret and I'm going to add the page that we are using for the login so right now we are using the home page for the login so let's type pages and let's type sign in and we need to set it to the home page right now we need to type const Handler it should be equal to next auth and we need to pass these auth options over here so let's tap alt options and now we need to export this Handler as get and post so let's type export Handler as get and Handler as post all right now the next thing we need to do is we need to wrap our whole app with a session Provider from next auth so here we can see that we have this layout.js file and this wraps our whole app now here we can add the session provider but we need to change this layout.js file into a client component for that so what we're going to do is we're going to create a different file over here and we're going to add the session provider in that and we're just going to export the session Provider from that and we'll add it over here so let's do that let's go to the app folder and let's create a new file called providers.js now in this the first thing we will do is we will change this into a client component so let's tap use client and then we need to import session provider so stop session provider from next auth react and then we need to export const and we'll just name it auth provider and here we need to add the children so let's tap children over here and let's create this error function and let's return a session provider and in this we will add the children so let's type children over here now let's go to the layout.js file and here we can see we have the children so this is all the content of the app so let's wrap this with the session provider so let's type auth provider and we'll just import it from providers and we will add the children inside the auth provider so what we are basically doing is that we are importing the auth provider from these providers and we are passing all the children that we have over here to here so now everything inside the app is wrapped with this auth provider right now we will be able to use the functions inside next auth so now let's go to the login form component and let's write the code for the login now first of all let's change this into a client component because we're going to use some user interactions over here so let's tab use client and just like we did for the register let's go ahead and create States over here to store the values from the input Fields so let's type const email set email equals use State and let's import it from react and by default it'll be blank and we also need to have the password so let's type password over here and let's also create a state for the error so let's type error set error use State and blank right now in this input fields we need to add an on-change event listener so let's tap on change and let's type e and let's create an arrow function and let's type set email and we need to set it to e dot Target dot value so this will set the value of this input field to this state and let's do the same for the input field for the password so let's tap on change e and set password let's type e.target dot value and now here we have this error so let's add this inside a conditional so let's type color braces and let's tap error Ampersand Ampersand so this code will work only if we have the error value and let's add all of this inside this conditional so let's cut this from here and add it over here now here instead of error message I'll just print the actual error message so let's tap color braces error right now if you go back to our website we don't have any errors but if we add some error over here so if I just tap invalid details now we can see that the error message is displayed over here so let's delete this right now let's create a function to handle the submit so let's tap const handle submit and let's call the function over here in this form so let's tap on submit and step handle submit but now the first thing we need to do is we need to prevent the default Behavior which is the reload of the page so let's type e dot prevent default right now let's add a tricaster block and here in the try let's tap of it and we need to use the sign in function from next auth so let's import that over here so I'll just type import sign in from next auth react so here let's type of it sign in and you need to pass the name of the credentials provider so here we have named it credentials so let's type credentials over here now since we are using aved we also need to change this into an async function so let's type async over here and here we need to pass the details so let's create an object and here we'll pass the email that we get inside the state from the input field and then we need to pass the password and by default it will redirect to some page so I'll just set the redirect to false and let's store this inside a constant solid stop const res equals await sign in but now let's check whether we have any errors so let's type if rest dot error we need to type set error and we need to set the error to invalid credentials and then we'll just return from this function now if you don't have any errors then we'll just redirect to the dashboard so let's import use router so I'll just tap import use router from next navigation and here let's type const router equals use router and here let's type router dot replace and here is tab dashboard and here are the catch ls.console.log error and now let's see whether this works so let's go back to our website and let's click on login and here we can see that we are taken to the dashboard now let's also quickly write the functionality of log out so let's go back to the dashboard and here we have user info so let's go into the user info and here we have the logout button so we need to import the sign out function from next auth so let's tap import sign out from next auth react I'm going to change this into a client component so let's type use client and here in this button let's add an on click event listener so let's tap on click and he will just call the sign out function now when we assigned dot we should not be able to access the dashboard page so let's go ahead and create a middleware for that so let's go to the root of our application let's create a new file called middleware dot JS and here we need to type export default from next auth middleware and you need to export the config so let's tap export const config and then you need to type matcher and you need to add an array and you need to add an array and we need to add all the pages that we want to be protected so here let's add dashboard right now this dashboard page will not be accessible when we are logged out so let's go back and let's click on the logout button and here we can see that we are taken back to the login page and now if we go ahead and go to the dashboard we are redirected to the login page right now if you go back to the rod.js file of next auth here we can see that in the authorize function we are just returning the user but if you return null and now if you go back and if I click on login we can see that it says invalid credentials but if we return the user then we'll be able to login right now let's write the functionality to log into our account using the data from mongodb so let's go back over here to authorize and here we will add the logic so here the first thing we need to do is we need to restructure the email and password from credentials so if you go back to the login form dot jsx file here we can see that we are passing the email and password so let's go back to the route.js file and I'll just delete this line of code and let's tap const email password from credentials right now let's add a try cash block and the first thing we need to do is we need to connect to the database so let's Tap Away connect mongodb and let's import it from lib mongodb and the next thing we need to do is we need to get the user with the email ID that we get over here so for that we need to type await user and let's import it from Models user dot find one and here let's pass the email and let's store it inside a constant and I'll just name it user and now if you don't find any user then we'll just return null so let's tap if exclamation user which means if the user is null then we'll just return null now the next thing we need to do is we need to check whether the password is correct so for that we need to import bcrypt so let's type import bcrypt from bcrypt JS and here let's type of it becrypt dot compare and you need to pass the password that we get from credentials and also the password that we get from this user so let's type password and then we need to type user dot password and let's store this inside a constant and I'll just call it passwords match and if the passwords don't match we'll just return null so let's stop if exclamation passwords match return null and if everything is all right we'll just return the user solid step return user and here in the catch I just type console.log error error and now let's see whether this works so let's go back to our database and here we have John so we have the email as John gmail.com and the password I have set is one two three one two three so let's type John gmail.com and let's input a wrong password and let's click on login and we can see it says invalid credentials but let's import the correct password so let's tap one two three one two three and let's click on login and now we can see that we are logged into our account now here we have hard coded this data so if you go to the dashboard page and if you go to user info here we can see that we are directly adding this data over here so if you log out and if you log into another user so if you log into Amy so I stopped Amy gmail.com and let's add the password and let's click on login and here also it says John and John gmail.com so now let's get the details from the session and let's add it over here so for that we need to import use session from next auth react and here we need to restructure the data so let's have const and let's tap data and I'll just rename it to session and we're going to get it from use session now in the session we will have the name and the email so here instead of John let's tap color braces session and if you have a session we will have the user and if you have the user we will have the name so stop dot name and in the same way let's go ahead and do that over here for the email so let's tap session user email and now if you go back here we can see that the details of Amy are displayed over here now the last thing we will do is we will restrict the user from going to the register or the login page when they are signed in so now if you go ahead and type register we are able to go to the register page so this should not happen so now if you go back to dashboard we are able to go back to the dashboard because we are signed in so when we are signed in we should not be able to go to the register and the login pages so let's go to the register page so here we have the register page and here let's add a condition and let's check whether we are logged in so for that we need to import get server session from next auth and we also need to import redirect from next navigation and then we also need to import the auth options so let's go to this route.js file inside next auth and we need to export auth options as well so here let's type export right now let's go back to the register page and here let's type import alt options from this route right now let's go ahead and type const session and we'll just set it equal to await get server session and we need to pass the auth options and since we are using await we need to change this into an async function so here let's type default async function right now let's add an if condition and let's type if session so if you are logged in then let's redirect to the dashboard or else we'll just return register form so now if you go back to our website and now we are logged in let's go to the register page and we can see that we are redirected back to the dashboard and we need to do the same for the home page because that's our login page so let's go to the home page which is this page.jsx file over here and let's copy the same things from here let's go back to this page and paste it over here let's type const session equals await get server session both options and let's change this into an async function and here let's add an if condition and let's type session redirect to the dashboard or else we'll just return the login form right now let's go back and we have some problems in the import so this path is different from the register path so I just import it again so just type import odd options from this path and now let's go back and we don't have any problems and let's go to the home page and we can see that we are redirected back to the dashboard but if you log out we are taken back to the home page and now if we go to the dashboard we are redirected back to the home page so everything is working all right and with that we have completed creating this app so we have created this authentication app using next.js next auth mongodb and Telvin CSS so that's basically it for this video if you have any doubts you can ask in the comments below I will leave the link of the source code in the description of this video so if you like this video please click on the like button and subscribe to this channel to get the latest video updates thanks a lot for watching have a nice day
Info
Channel: GTCoding
Views: 34,738
Rating: undefined out of 5
Keywords: gtcoding, Next.js 13, NextAuth.js, MongoDB, Tailwind CSS, Next.js Authentication, Custom Authentication, Email/Password Authentication, User Login System, Next.js Tutorial, Web Development, Web Development Tutorial, Full Stack Development, Next.js 13 Authentication Tutorial, Next.js 13 Custom Auth, Next.js Authentication Setup, Next.js Authentication Guide, Next.js Authentication Example, Next.js User Login, Next.js User Authentication, Next.js NextAuth.js Tutorial
Id: PEMfsqZ2-As
Channel Id: undefined
Length: 63min 25sec (3805 seconds)
Published: Wed Aug 02 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.