Use Lucia instead of Next Auth - Lucia Auth Next 14 Username Password Authentication Full Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone this is ur and in this video we will Implement a username and password authentication in nexj 14 app directory using Lu which is a great library but it it might be a bit challenging but I I'm sure that it is easier than next out we will use types script Z Library shedan Tailwind post SQL as a database and as a we will use DM so let's see the demo I have a user created here and we check if password is right once we logged in we are redirected to a protected route if I sign out we can see that I can go back and I have also sign up page that I can create accounts if I create accounts I redirect it to protected rout today we will learn how to do it so let's get right into it first of all let's create a brand new NEX gs14 app I will go to its official website and we can simply copy this code here and I will open up a new terminal navigate to my documents and paste the command here it will ask bunch of questions let's say Lu out for the project name and I will just simply select the defaults okay our nexts application is installed I will type code and Lucia out to open up visual code I can now open a new terminal and run mpm run da command and our next yes app runs at 3,000 perfect now let's go to Lucia's website here before we go into deep I want to talk about Lucia a bit it's an out library for your server that abstracts away the complexity of handling sessions many people arguing about next out nowadays and people complain about the abstractions that they they made is too much and no one understand their docks so even though Lucia does some kind of abstractions but it is not much as next out does and the documentation is clearer even though they say they have plus 100 contributors when we follow this link and go to their contributors we say that almost every lines of this package code is written by the owner of the repository on paper so it really depends on one person right now and if you don't like this it's totally understandable and you can just wait a little bit more to get more popular and get some contributors but I really believe that Lucia has a lot of potential and it will gain some popularity as time passes and it has 6.3k stars right now which is a good sign lastly I want to mention that Lucia provides session based authorization so no JT token here but we may talk about the difference between a token based authentication and session based authentication in another video let's get started with Lucia I will click getting started here and we will need to install Lucia and Osa package Oso is a third party package that is implemented by the same person who implemented Lucia whereas it is not required it is recommended so let's install this I will open a new terminal here and past okay it is installed now they say you need to initialize Luci and the given example works with SQL light but we will use post SQL so they have a database section let's go to there and they say a database needs to have an adapter as you can see it is adapter for esql light and we will use drizzle o and let's go to there and now they say you need to install this I copy it and paste it here it is installed but I forgot to mention something since we are using nexj 14 with turbo support we need to add a configuration into our next GS config file I will simply look at next GS app router and copy this web pack object here and go to next config file and paste it here if we don't put it here also package will throw an web pack error okay now we are done that and we have have installed um adapter uh drizzle adapter and now I would like to go to drizzle orm's website and install the necessary packages I will go to documentation and from here I will click on post SQL and we will select node post I will copy it and paste it in my terminal after that I will navigate to drizzle kit and here we need to add a new configuration file dzel config.sys might be undefined let's put an exclamation to say that it is a string and we know that and the warning is gone now everything seems okay let's go back to Lu's website in database there is LM page we will see they have an example poq so they initialize a database object and also Define their scheme and they initialize an adapter here what I'll do is copy all of them and go back to my application I will create a lip folder and inside it I will create another folder called DB and then I will create an index file here and paste all the things I have copied this will take some params as you can see it gets a client we can either Define a single client connection or pool which is preferred if you send frequent requests so that's fine but in this pool object it also gets an configuration as you may see so if I take a look at here it has also connection string and we will just give the same URL and we are done and we are defining some tables here user table and session table and an adopter here so we can split the logic here let's move this into another file and Export our DB from this file I will create a new file called schema. TS I will paste the code I have copied from the previous file and I will grab the import from there paste it in schema. everything seems fine and let's export adapter from here and we will import DB and everything seems fine and it's better to separate the files which schemas are defined in another file and database is defined another file right now user table has only ID field in our case we will need to have a username and a password let's call it hash password we also want to support Google log in so I will say Google ID as well since someone logs in with Google it won't have an hash password so let's remove this not null here that's enough for user table for now we exported this adapter is because we will use it to initialize Lucia so let's go to Leb and create a new file called out. TS and go back to luci's website and copy this code here it initialize a new adapter here but we don't need it so we have already defined our adapter and we are just importing it let's create a post SQL database I won't use a cloud service for setting up a post SQL but I will use tuer to set up a local post SQL container and I will give that URL here but if you use external services like like Railway or neon and they will give you a database URL you can just simply put that in here and if you want to create a container we can create a post SQL database with this command we will say Ducker run and it will run in the background so we will get pass at D for Damon and we will give a name it will be our container name let's say postgress TV and we will pass an environment variable which will be postgress password let's call it my secret password and we will map the port from 5432 to um 5432 and we want postgress image when I run this comment I see that a container is set up I can actually see that here our database is running and DB URL will be this one so we are using a post connection and the username is pogress password is m my secret password and it runs at Local Host 5432 and database name is postgress perfect then we can go to package.json we will add some scripts here DB push and DB Studio this will push our schemas into database and create the tables and this will open up a local nice UI to see our tables so let's run BB push now okay we get an error it says no schema files F okay let's see where do we give this it in there is a config TS and our schema. TS is actually an app lip DB so let's change this I go to there's a config and I will add app lib and schema TS is there let's try to run DB push again okay I forgot to add DB here when I run it again it says no changes the ected it's weird but let's run mpm run DB studio and it gives a URL like this let's open it up and I don't see anything okay so it says cannot read properties of unfined tables get Tables by schema is not working and one reason might be when we look at schema TS we see that our tables are not public this it's a decision that isn't made so we need to those exported in file so if I run mpm run DB push again you see that now they took our tables and turned it into SQL statements and they say do you want to really run this I will say yes and changes are applied so let's run DB Studio once more once I refresh I see that our user table is there and station table is there as well perfect we are done initializing the database so we can move on create pages I will create a Pages folder that is in Brackets which will make things easier to understand and I will create a sign up folder here and create a file P TSX I have exported sign up page and let's go to local house 3000 and go to sign up sorry sign up and we see that sign up here I won't Implement all page here but I have this code that I have written earlier and let's let's comment this out and you will see we have a page that has a logo and a title so let's implement this signup form I will create a components folder and create a component sign TSX perfect then I can just revert this and import sign up form here so we are now seeing our form here for the form we will use Chet CN so let's go to shed cn's website and go to docs installation nexts so start from step two open up a new terminal here and paste this command I will say yes to everything okay we are installing the dependencies and it is done for this project we will add and form button input and toast components it's installed so let's go to components and find form here and we will just simp simply copy this example okay it says usage okay first of all let's copy this go to sign up form and put that here and then we are defining a form um I think we can copy this and paste here and import use form and R res perfect lastly let's import lary components button form and input we have already installed them and this is a very basic components that is given as an example so let's take a look at what we have okay we have a label an input and a description so let's get rid of the description we don't need it perfect but we need to have two more Fields one for password another for confirm password before changing them we will need to edit the form schema okay we will add a password field which will be a string and let's give minimum 8 characters and then give a message password must be at least eight characters long and let's add password as well we are done with that we also need to be sure that confirm password is same as password so we will call refine function and it will get a parameter that is the form we have and we need be sure that data password is equals to data confirm password and it also takes and confir configuration parameter that we can actually give a message and we need to also Define a path so that this message will be seen in this field we will see in a bit so we Define our schema and we will need to give default values and just give empty strings so now we can edit our form Fields this one will be password and we we will say password for placeholder I will just put Aster here and type will will be password so second one will be confirm password and placeholder will be again some asterics type will be password as well go back to our app as you can see we have a basic form here dat spacing seems a bit off to me I will just change it to two it's better I can click on submit as you can see and we get some errors and if I type some password you can see password do not match perfect so everything seems nice but I like having schemas in a file that's why I will create a new folder in app directory called types and I will have an index TS there then I will simply grab my schema and put it here we will import Zod and then export form schema and I will call this sign up perfect and when I go to form we now have some errors so let's change form schema to signup schema and import this schema awesome so we have now a types file that we we can Define our types okay let's Implement unsubmit button what we want is when unsubmit is called we want to call a function that saves our user into our database for that I will create an actions folder in that actions folder I will create a file out that actions. TS which I like this naming as our application grows it make things easier for us to understand I will mark this file with us service so that we know all functions will run in the server not exposed to outside so here I will have sign up function and we will export it and it will take some values its type will be the same with this we will import Zod and our schema so let's log it go back to here and call this sign up function and give our values let's see I go here open up our console just type something so we are seeing our values which logged out in the client and if we take a look at the server console here we can see that we also get this value in the server in this function we have username password and confirm password and we are sure that password is to confirm password Here we need to Hash this password here let's Define a variable hashed password and we will use Alla package for the encryption so I can say new argon 2 sorry argon 2 okay and it comes from Oslo SL password package and we will hash this give it our password so right now we have a hash password but since it's an a sync operation as you can see it DET returns a promise we need to await it we will make our function a sync so that we can wait for this function to be resolved after that we will generate a user ID using generate ID from Lucia it expects a length so we will give 15 right now we have a hash password and our username is ready user ID is ready so let's call it our DB I can say db. insert into user table with the values of of ID is here username and password it's that easy let's return ID and username maybe we can use those information in a toast perfect but we need to also wait this so I put a wait let's wrap this function with try catch block so if we get an error we will simply return error that message and let's give it any type we have successfully created a user in our database and now we need to create a session for it we will call Lucia and import it from out file and we have lots of functions we will use create session and pass our user ID as it is expected then we can give some attributes to it for example expires in so our session will be expired after 30 days and it's an a sync operation create a variable and assign our result to it we will use Lucia's create session cookie function and pass our session ID to this function now as we have session cookie we can just call cookies from next headers and set this session session cookie. name value and session cookie that's. attributes then we can simply return Success Through data user ID perfect we have completed our signup function let's make this function aing and let's wait for the result and assign it to a variable like rest and we can just simply check if rest. error exists and we will import TOS from sheden and varant will be destructive and description will be the rest error otherwise we will check for success and if it's successful rant will be default let's try go to our application and type something and hit submit okay nothing happens okay we actually know that our function is being called sign up but we don't see any toast so yeah I I think I got the issue it's because we didn't put TOS wrapper inside layout here so we will put our toaster from chn and we should see now some kind of okay it says duplicate key violates unit constraint so it's probably we already created this account so let's see yeah username admin and hash password we have some password here but if I let's say create another user an account created successfully perfect so after creating our user we need to redirect them to a protected route so let's make root page is protected for this let's use use route Hook from next gs14 I will call it router and use router will be from next navigation after this TOS we will call router. push and it will go to the root and let's try out admin to and see we are now seeing the root page so we have created a session and we can see that from application and cookies we see that um out session is there and it has some kind of value in it right and if we take a look at the result Studio we can see that we actually have this where is that AGP value is here how do we validate session is checking this value is exist in our session table and if it is not expired or not so for that they have a guide valid dat session cookies in nextg app router so they have an example of this we will grab it and copy then we will go to our out. lip that we have initialized our Lucia object and put it here and we are caching this so that we don't send multiple requests to our database and we import cash from react and next headers from cookies from next headers they have a get user function but we will change it a bit so we need to volid validate the request right so let's call it validate validate request and we get session ID from uh the cookies if it is not exist let's return user null and session null we are Rel dating session with Lucia and it returns a user and a session and in here if session exist and session fresh we are creating a new session cookie and set this in the cookie if there is no session we create a blank cookie and set this blank cookie and we will instead of returning the user we will return user and session as well so we have now a validate request function and let's export it so that we can use it from other Pages um as we want to make this page protected so let's go to that page page in here I can say that let's make this function a sync so that we can call our validate request I will grab the user from oh sorry uh from uh validate request that we created and if user is not exist we can call redirect from next navigation and to sign in page and we we want to return it so let's refresh the page as you can see I can see that page but if if I remove this cookie I should be redirected to signin page which we don't have a signin page we will have in a bit actually let's create this one um I will copy sign up folder and paste it here rename it as sign in I will change this copy of it sign into to your account and we have this sign up form which I will again copy and paste it once more let's call it sign in and we will only remove confirm password here and go to schemas and create a new one that we can remove confirm password and let's remove the refine as well call it sign in schema and we exported it so we can go to signin form and use it instead of sign up schema and everything seems okay and we want to say sign in okay no sign it in successfully and and let's go to here and remove this form field for confirm field and okay why it gives an error let's see username password is not assignable parameter of username password and confirm password so where does that confirm password come oh okay it's actually it's because of this function so let's go to here and create a new function for sign in what we will do is create a new fun function sign in which will be an snc and schema will sign in schema in here we will call our DB we will query it to to user table but we get an error property user table does not exist seems like schema generic is missing did you forget add it to your DB I think we did and dbts go to dbts and it says record string never okay here dzel takes a config uh config parameter that we can pass our schema here as well and we can import our schemas like this import a schema from our schema folder and now we have an issue with this DB type any and we can uh type this as it's a node PG database which is type of schema okay perfect so so when I go to go back to out. actions and I type a DOT I can see our tables now and dbquery user table we will call find first it's a function that takes a config parameter and we can use where and where is a function that gets the table we can return equal this comes from there is orm so we can check if two Val is equals or not and yeah we just checked if this username is exist in our database so assign it to a variable we await the query to return and if there is no existing user we will return an error user not found if it pass this condition which means that existing user is there so we will check if is this password given is valid so like this and now it says hash password can be null it's because if user logs in via Google or any other social account we want start hash password let's type an early return here if hash password user not found and now is valid and now error is gone and we can check if is valid password is a f Val we can return invalid password or actually we shouldn't say that we can say incorrect username or password so we don't give any information about the user if we pass this condition as well which means that we need to log user in that's why we will do the same thing that we did in signup function let's copy this and paste here and user ID will be existing user ID it is same and we will return a success and message will be be logged in successfully so let's go back to signin form and change this with sign in and the error is gone now perfect so let's take a look at sign in page it says sign into to your account but we have confirm password I thought we removed it okay we removed it but oh okay so let's we need to go to the signin page signin page it's still sign up form it should be sign in form but I think we didn't did we okay we export as sign up form it will be sign in form and we will import it in the page yes it says sign into your account perfect so let's try it admin and I click submit okay what is going on let's take a look at application anything is here I click on submit and nothing happens okay we it says cannot access blah blah before initialization I wonder what we did so so let's take a look at out actions okay so um I have looked at the shuee and fixed it and let me tell you so we are we were also exporting this adapter here which uses DB object here but in our index.ts we were initializing DB in here which requires the schema which which we imported everything as schema which was also supporting the adapter as well but adapter depends on DB so that's why there was an issue and I I have just remove this and created an adapter file like adapter. TS and put it here so in here in index TS we only import the tables right now and we don't need those as well so that was the issue but don't forget to update out. TS update this pad in out. TS where we use adap so let's take a look at the application so when I click on submit I get incorrect username or password let's try it again it says okay we have signed it successfully and we can refresh the page and I still see the root page lastly let's Implement log out functionality quickly all we do is go to out sorry out. actions and create a new function call Con sign out and um we will we will get the session ID from the cookies so um we can actually use con session wait validate request here that we implemented in out file if there is no session we can return an error no session is found or or unauthorized and after this we will call Lucia and invalidate session and we will give the session ID to it after that we will create a blank session cookie and we will set the new cookie it's that easy and let's wrap all of these inside a TR catch block and let's give it a tie ER any and let's switch switch to page. TSX which which is our protected root we can say and let's also stringify the user and we see that it's protected root and let's define a form here just a quick form and we will have a button sign out we will have a type of submit and and we will have an action here that and we will call sign out function and it's that easy beautiful now we have a credentials log in and we can log log in or log out if I logged in and try to go to a signin page I can still see this page which doesn't make sense since I have a session so let's fix it finally and uh close this and and finish this videoing page I can I can validate the request and make this a sync and if there is no user I can just return direct you can see that if I try to go to sign in so sorry sign in page I am redirected to protected route and you can do the same thing for sign up page as well we will do the same thing for here as well let's import this make a a sync and import your direct from next navigation see let's try to go to the protected route I am redirected to sign in but if I sign in I get signed in successfully and I can go back perfect and thank you for watching I will also record a tutorial about how can we add Google sign in functionality but it will be in a later video okay take care byebye
Info
Channel: Ugur Codes
Views: 2,928
Rating: undefined out of 5
Keywords: nextjs, postgresql, next14, vercel, typescript, shadcn, lucia, joshtriedcoding, luciaauth
Id: JIIy7VkiTqU
Channel Id: undefined
Length: 34min 6sec (2046 seconds)
Published: Sun Feb 18 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.