Next.js 14 Authentication Tutorial with Clerk and Lucia (super EASY!)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
authentication can get really complex really quickly you have to know the bre practices as well as the security principles on top of this you also need to know how to manage CH tokens what they are user sessions user management two Factor authentication go and a lot more because this is just the tip of the iceberg I have implemented authentication from the ground app and trust me it's a lot of work and also it's really complex so in this specific video I want to walk you through two popular libraries one is clerk that does it all for you and second is Lucia that abstracts away the complexity of managing user sessions so we will be deep diving into authentication in this specific video and we will be adding o from the ground up that is clerk as well as Luci o in two different apps and I will be walking you through the trade-offs we have to make as we build these apps further so let's get I went on Twitter and asked folks who are the top players in a and as far as I knew they were next o super base o Clerk and so on and I wanted to ask others what are some authentication libraries that they like so obviously we have clerk we have remix O then we have Lucia o we have aight next o o kit and there are other again Lucia again Lucia again plus this option for Lucia got the most wordss as well so that's why in this specific video we are going to use Lucia o and Implement o from the ground up so first let's take a look at this diagram and look at the challenges we have to go through when we have to roll out our own o or even why did we go for Clerk and Luci o for example in this video so when you have to roll out your own O then there are quite a few challenges one it's complex you have to know the security principles as well as the best practices you need to know the different types of tokens the expiry of them user sessions cookies and there's a lot more so there are quite a few challenges when it comes to rolling out your own op so you need to know what you're doing to essentially do this in this specific video we are going to use Lucia o and Implement o from the ground up but why Luci o what is so special about it well if you take a look at all the different ways you can Implement o we have remix o super base O next o and so on on the the other hand we have odd zero Firebase and cler if you're okay to lose control when it comes to implementing authentication then definitely go for OD zero Firebase Clerk and so on they will manage it all for you you will have less way less control over what you can do but you will get a nice hosted o and all you need to do is Implement write a few lines of code that I will show you and then all that's it that's that's the the benefit you get but obviously there are tradeoffs wherein you have less control on the other hand we have remix o super base a next o and so on here again when it comes to implementing o and adding let's say sign in with Google or sign in with get up and so on it's definitely a lot easier than rolling out your own but still it's definitely open andate it because they have their way of implementing authentication that you sort of have to go with so for example in case of nexto if you have to roll out your own username and password then it is a lot more complex and it's not that simple compared to for example using something like clerk where all you need to do is just tell clerk this is what I'm looking for configure it and add it in your Cod and we will walk you through that as well but in the middle we have Luci o so let's take a look at what's so special about Luci luciaa definitely gives you a lot more control so this way you have to configure and you have to write a bit more code in terms of how you want to implement your o but it's still abstract away the complexity of authentication so if we were to head over to the documentation it will work alongside your database and then it will provide an API that's very easy to use and understand plus it works in any of the r these runtimes as well it's fully typed and plus you don't have to deal with a lot but you do have to configure a lot and know exactly what you're doing as well over here but Lucia o is definitely a lot simpler to get started and if you want a solution where you do want some control and but you also want the complexity to be handled that o provides you so Luci is definitely a good option where you don't want to roll out your own o and deal with the complexity there but with Lucia it will make it easier for you as it will provide the apis so that you can Implement your own o and configure it so you manage your own users you have full control of that as you need to configure your database as well and they give give you some options and tutorials and so on to manage sessions and Implement o or username and password and so on so that's where Luci a sits it sits between the managed fully managed o versus somewhat managed to in the middle where you can you don't have to roll out everything on your own but you can roll out something with Luci a so that's where Luci a is we will be setting up Clerk and then we will be using Lucia a to essentially Implement authentication from the ground app let me give you a quick walk through of the that we are building with clerk now this is essentially a clerk hosted model and we haven't necessarily build this model at all for sign up now by default on the homepage you would see a nav bar with o explained as the name of the app and also the hosted signup model if you already have an account you can click on sign in and then sign in to clerk as well sign in to your authentication layer as well similarly if you click on sign in from the Navar you should also be taken there now let's go ahead and create an account because right now we don't have one so for example we can just create an account with my email address and then I'm just going to use this to suggest the password then let's hit continue the minute we do that I now need to verify using the code that it has sent me because only the email option is available now the code is 892 261 so now it has verified the code and you can see that I have been redirected to the homepage with hello my specific email address and because the signin was successful now we on in the nav bar the signin button has changed to this specific option but you can also go ahead and manage your account or sign out again this is also built by clerk this is something that we have just integrated so if you click on manage account you can go ahead and update your profile photo or change your password if you like or even delete an account so you have full control and all of this is built with clar you can add several email addresses or even remove the specific email to I've uploaded my profile photo and now if I close this option you can see my profile photo along with my email address is is showing up on the Navar which is really nice and all of this is built using the clerk components that we will take a look at in this specific video now we can also go ahead and click sign out this way we are basically signed out but now if you go to the dashboard on clerk we should see our user that we just signed in with which is my email address and as you click on that specific user you have a lot more options to basically manage that specific user you could impersonate that user change your password ban user delete user and so on plus you can see all their information as well you can all you can also update their user permissions as well all of this can be done in clerk because clerk will manage all the users and you have basically some configuration options to update their profile and whatnot this is the app that we are going to build using Clerk and you will learn the power of using something like clerk now we have only enabled email address and password but in this specific video I will also show you how to enable Google login get any sort of oat as well so you can do all of that using clerk with just a few steps so that's the app you're building so first let's go ahead and Implement clerk now clerk is obviously more than just a signin box we can use admin dashboards to authenticate and manage users and so on now let's take go ahead and sign up now since I have already signed up I see this dashboard option but you see you should see a sign up option so make sure you go ahead and do that I'm just going to head over to the dashboard now we already have an app here o but let's create a new app and we can enable whatever we want in this specific application so let's just call this explained now we can enable whatever we want here so you can see all the different options we have signed in with Google Facebook Apple GitHub Microsoft LinkedIn Dropbox and so on now obviously when you select more of these options then you have to then upgrade to a pro account but really we don't want any of this we're just going to focus on username and password in this specific video so let's just go go ahead and only select email for example and let's go ahead and click on create application the minute we do that it is now giving us options for all the different Frameworks we can integrate this with now first let's just go ahead to the nextjs documentation because we will be using nextjs as a framework of choice so let's go ahead and install nextjs now so now let's go ahead and copy this and head over to the terminal now let's just paste it now here let's just call this app or explained clerk we're just going to go with all the default options and we will be using tailin CSS alongside Daisy UI to basically set up the look and feel of our app but for now let's just go ahead and select all of these options make sure you say yes to would you like to use rouder option and then hit ENT it's going to install the dependencies as well as the dev dependencies needed to bootstrap our app next we also need the clerk package in order for us to get clerk in our app so now let's go back and before we do this let's go and CD in a explain clerk I just paste this and we also need to paste this in our n.l file because we need the publishable key and the secret key key for clerk so now let's just open it up in Visual Studio code for example and now now let's create a new file called as. n. loo here let's just paste what we copied and that's a set up for the API keys and storing that in the environment variables before we go ahead and do anything let's make sure that our application runs as expected so let's just run npm run Dev which starts our development server and let's head over to Local Host 3000 and there you go we have our nextjs app and alongside that we also have clerk installed as well in our application so now as next steps let's just go ahead and follow what they show us here so now we're just going to copy this which is adding clerk provider to your app so we are going to head to layout and layout is a spot that wraps our entire application so we definitely need this so here let's just wrap oops let's just create clerk provider and wrap it in layout wrap our entire app with clerk provider we have imported clerk Provider from clerk nextjs similarly we also need this middleware file which basically enables the authentication and it separates the protected routes from the non-protected routes and so on and what this middleware also does is that it is going to be the middle person when we basically execute the page so for example anytime we call a specific route inside of NEX Jas then this specific file will be called and if we say that hey just route the user or log the user out if they don't have permissions to something we could do all of that in this specific file so again let's just go to our home and create a file called as middleware dods and paste it there you go that's all we need to add clerk authentication we have made quite a few changes so let's just go ahead and restart our app so now if I refresh the page we have the provider and we have the environment variables and all of that but we have not necessarily implemented the signin and sign in sign out Pages or even the sign up Pages for our app as well so our app works as expected and as we wrap the provider with layout and all of that but now we need to also add a signin and sign on pages so for example over here we have this model from clerk with email address and password and then when we hit sign sign in then we get the sign in option too so we have the sign up option as well as a sign in option when you go to sign in or sign up for example right from here or just go to sign in here or sign up here and so on so we need to implement this and in order for us to get this we definitely need to implement sign in and sign out and the way you do that in clerk is by going in the app directory what we essentially need is we need two pages one is a signin page so for example you can see I'm redirected to/ signin and the minute I click on sign up then I am going to the route sign hyphen up so that's what we need and at the same time if I go to the homepage and nothing really happens I get redirected back to the sign up page because I don't have a user yet but similarly if I had hit sign in and let's say enter my email address continue and then I forgot my password you can see that I can now enter whatever code I want as well over here so now so now if I go ahead and hit sign in then I can just pretty much select my option for my email address and then it populates my password as well because I have already signed in before and now it tells me that hello and my email address that I used to sign in has been displayed here but at the same time this specific option has turned into a way that I as a user can manage my account so if I hit on hit manage account and go to security I could update my password I could change my user profile and add whatever add whatever image I want as well over here for example so I could do whatever I want here and this has updated my image here too so this is how I could manage all of this in clerk so we want to implement something similar inside of app as well right here now let's go ahead and add Daisy UI which is a very popular component library for tailin CSS this way our our form looks really beautiful by just using Daz UI so the way you use this app this library is by first installing it and requiring it in the tailin config file which is the global configuration file for Tailwind CSS now again they have options for next GS they have different repositories as well but it's pretty straightforward so what we're going to do is we're just going to copy this and install it but before we Implement and add Dy UI inside our app let me show you how it works the way you add Daisy UI is by basically going to any of the components that you want which it has a lot of different components and just let's say if you want to add a button then all you need to do is go to the button and however you want your button to look you can just go ahead and copy the HTML or GSX code in our case to basically copy paste it exactly as we want now what dcui does is that it uses specific class names such as BTN neutral primary secondary accent info success warning error and so on so it's also is able to switch us to a different theme and we are able to modify these colors to whatever we want so our application looks consistent as well but let's say if we want drop down then all we need to do is add some class names and we get drop down as well and it has a bunch of different components in our case we'll mainly be using whatever is needed for the form but what we also need is some sort of a theme for our application so we could head over to a theme generator and then generate whatever theme we want or on top we could just go to Daisy UI themes and select from a bunch ofe pre-existing theme so for example we could go with retro Valentine dark cupcake and so on which is pretty nice because you get a really default beautiful looking theme so your application starts to look good already so that's what we'll be using in the specific tutorial so for example let's just go ahead and copy this again in case we didn't to install Daisy u in our app so let's stop the server and paste what we just copied again let's restart our server again and now let's head over to our code and go to tailin config file and in plugins what we need is we need to go ahead and add require Daisy UI so here whoops here we're going to say required AI similarly in order for us to add the themes we're going to say add an object for daui with themes now let's go to our app and again do the same name here now this would apply the theme cupcake for example but now if we go here and refresh the page you can see there must there was some changes but not really because we still have our app exactly we still have this specific page as well so let's just get rid of everything inside of main here and now let's just wrap this up with a simple main tag and now let's just go ahead and add some basic styling to our so for example here let's just go ahead and add a button for example now let's say we want a primary button so we going to copy that and now let's just paste what we copied we can get rid of this as well this would add the class name button with button primary so that the specific colors for that specific theme gets automatically chosen so now if we head over to our app you can see the primary button does look like the theme that we have applied but we also have this weird colors so let's just go to global. CSS right here inside of app and pretty much get rid of all of this because we don't need it similarly we can get rid of this as well this is just the pre-existing styling that came from nextjs app but we don't need it and now look at that now we have some colors applied as for the theme that we have applied in one really cool thing about clerk is that it already gives us these bunch of components that we could just use in our application so for example sign in sign up sign in button sign up button and so on so we can just use these and we don't have to create anything on our own but they also give us some customization so that we could make the UI look according to our brand so that's exactly what we'll do now so for example in our app what we can do is let's go ahead and add this sign in button for example so we would essentially go to layout for this so if you go to layout here we have the cloak provider but let's also go ahead and add a header right inside body right inside body so for example let's say you're going to say header and then and then we're just going to paste this code right here now as you can see that I have not necessarily filled or imported any of these buttons here so if I click on sign in then user button then again sign in is already imported all of these are actually coming from the clerk nextjs package itself same thing we want to do for sign out button and sign in buttons and so on so what we're going to say is hey this is the Au explain repo and right now it is a a tag let's use a next link component which basically points to home and then over here we saying if it's signed in then show the user button but if it's signed out then show the signin button for example so now if we head back to our app now you can see this signed in option which takes us to the signed in hosted clerk UI for example but keep this in mind this is not necessarily in our Local Host it's actually hosted somewhere else so in order for us to implement the signin button let's go ahead and add the signin page in our application now let's go ahead and add a route called AS Slash signin similarly let's also go and add a route called as/ signup and the way we would do that in clerk is by creating a catch all route that's what it requires us so what we could do is we could say sign in and this would mean that any type of signin route is going to get routed here just going to say page. DSX now above this we also need a folder so so let's just move this folder out and then this sign in would be right here so this is how you need to define the catch all route for signin and catch all route would mean that anytime user enters anything inside of signin is basically going to go here here we're just going to say export default function page and this is just going to be the next yes page but here what we would want is our signin page so again we're going to use the signin component cler so first we're just going to wrap it up with a class tailin classes we're going to Center the div as well so that it's centered on the page and we're just going to give it a gap of 12 now let's go ahead and add the signin functionality here so now what we're going to do is we're just going to add sign in from clerk so that's what we need need we need signin functionality and then here we're just going to say the path is going to be/ signin this way it knows that that that's where it needs to host the login for clerk so now let's go ahead and see what happens so now when we head over to slash in nothing happens because we we haven't defined sign in properly we just need a hyphen right here now if we go back and refresh the page look at that now we have our signed in hosted UI ready to go from clerk so for example here I could basically just log in and you know continue now it could not find my account so I will just go to sign up for example but again if you notied sign up is taking me to the clerk development mode this is a developer environment that Kirk cler provides so we can see what are hosted Lo in and sign up look like but we need to create a sign up page similar to signin so that when you click on sign up it goes there compared to the other URL that we were looking at but here we can basically sign in and you know essentially go ahead and do that but now before we can Implement and check it out let's Implement sign up so now similar to how we implemented sign in let's also Implement a sign out route so if we go back we could just pretty much copy this or let's just create a new folder doesn't matter just say sign up and now inside of that we need to create another folder catchall route so all the sign up parameters get caught here and let's create a new page. TSX which is the default page here we can copy this and paste sign up here but instead of sign in it's going to be sign up now let's paste what we copied and sign in this is is going to be sign up that's all you need so now when I click on sign up and everything has is working as expected then we should be redirected to sign up the minute I do that nothing really happens but if I go to sign up let's make sure everything works sign up does work as expected when I click on sign in it still takes me to this completely different route and not within the application and the way we can fix that because it right now takes us Direct ly back to a different URL alog together is by defining environment variables right here so here we can just say next public and here we're going to define the sign in and sign out route so clerk knows that's where it needs to redirect so it's very it's pretty straightforward we're just going to say clerk sign in url similarly we're going to say here clerk sign up URL and here we're going to say it's going to be sign in and over here we're going to say it's going to be sign up the minute we change make changes in the environment file we need to restart the server so let's go ahead and restart the server now once we refresh the page when I click on sign in it does take us to the app similarly when you click on sign up it does take us here now let's go ahead and create an actual account here so here I'm just going to use the email address and password I had and hit continue and the verification code is 441 050 now as I verified it you can see that my username is shown over here and it has a clerk hosted menu bar here which is pretty awesome because now it knows my username so as a user I could go and manage my account I could update my profile I could just go to my profile pck and update it I could change my password if I want as well and I don't need to build any of this as a developer I just need to use pretty much a few UI components to integrate cler so now the way we are enabling that is by again using when it's signed in it shows the user button and this property show name shows the name as well so if I don't want that then I could just not have it for now let's keep it similarly if I were to go ahead and click on sign out I'm back to the homepage and it shows me the signin button which is what I want now by default default we probably want the signin model over here as well just in case the user is not logged in for example so what we can do for that is go to the page file and in this case we could pretty much get rid of this button and here we're just going to check if the user exists or not clerk comes with a lot of different hooks that are really handy while building our authentication layer further so for example we have so so many books available in the do documentation for example we have the use user hook which basically allows us to access the current user data whenever you need it so let's say you want to show current user information for example from the user object then you can you can as well for example if you want to get the first name last name and so on similarly it has the Ed sign-in hook for example which allows you to check the current state of signin similarly it has so many different hooks that we could utilize to get specific information about about application about the authentication that we have set up with clerk so that's exactly what we're going to do in our case as well so in our explained app or the app that we're trying to replicate for example over here by default we show a sign up page for example let's say we have signed in and we hit continue then we show a hello user and a photo next to the email address for example in the Navar we have this implemented but we need something something like this as well so that's what we will Implement here so for example we're going to use one of the hooks that is available to us so for example we can say user is going to be current user which is which is a hook from Clerk and then let's make this function async because we are calling it an we over here now inside here we can check that hey if there is no user then we want to return the sign up function ity that we had so for example if we take a look here we want to just copy this and paste it here and import sign up we don't even need to say path equal sign up we can just sign up but let's say we do have a user then we want to share something else too so again here let's just give it Flex Flex call padding top 12 which is going to be three REM item Center justify Center as well and a gap of 12 now let's give it a P tag and here is where we're going to say hey welcome back let's add a emoji with the wave and Emoji over here and then just say hello we can access user safely here because we're already checking if it doesn't exist here so here we can say user. user username or in our case email address for example of zero. email address now since it's typed we can already check this is the user object from current user which returns a user value and these are all the different properties here and email addresses is in fact an array of email addresses which returns a property called as email address so we could just go into the types and check exactly what we should access now we've got this information now we have the list of email addresses and then if there's no user we just want to return the sign up now let's go back to our app now you can see that we already have a hosted sign up page here and let's say we were to sign in for example and hit continue you we see hello my email address that I used to sign in which is very similar to the now in order for us to make the app look exactly how we want it to instead of calling it cupcake we could call this retro now look at that has started to look very similar to this specific app which is what we want you can only obviously give it a class name here so you can say text 2 Excel or let's say text 3 Excel now you can see that our app is this or even this both of them are looking pretty good the app that we trable so now we have this let's say we were to log out here now you can see that the hostage sign up model is on the left hand side the clerk gives us another property and it's called appearance this allows us to customize the appearance of these specific posted models that we get in here we have Elements which has specific properties that we can use so for example we can say root box is going to be MX Auto and then we're going to give it padding similarly we can change the primary button color to be whatever we want so we're going to say background color and here is where we can pass in whatever hex code that we want as well or whatever selling we want we can easily add it here because of this appearance prop object now when we go back you can see already that it's actually in the center with the button color has changed to purple for example now our clerk little model is looking really nice we have The Branding necessary as intended but now notice that there is a specific error as well that we should definitely resolve it says that the signup component is not configured correctly and it's because the root route is not a catch all route so whenever we have to use sign up or sign in we need to use a catchall route as clerk requires us to so in order for us to fix that we need to do something similar as we did for sign up and sign in so here let's just add rest and then move the brute page to here so it will act as the same as before because the rest is a catchall route and we haven't defined a root route here this means page is going to directly be the default page for any of the queries in the URL so now if we go back here you will notice that the error is gone so now everything works as expected but notice one more thing this is a purple button whereas everything else is isn't so let's go ahead and just copy the appearance that we have in the rest of the Pages as well cuz we haven't done that really so here as well so now when we go back you can see that the primary button is purple same thing for this one same thing for everything else too which is exactly what we are looking for so that's the beauty of clerk like we were able to set up a authentication layer and a base o in just a few seconds because it makes it that easy for us to set up our entire a layer now obviously a is a lot more complex than this for example we want to access specific values about the user and things like that and for that reason we have all these different helpers or these hooks that we could use alongside uh the clerk o layer so that we could so we can use these hooks that clerk provides us which are sort of like helper methods for users that are signing in and signing up so we can can access any of the values that we're looking for for our users for example which is pretty neat so now when it comes to using clerk there are definitely some trade-offs as well for example we can go to the dashboard to manage all of our users that I've logged in but this means that we need to use this dashboard and clerk is going to manage the sign in sign out the sessions or whatever we have configured so far on their own so we have less control in terms of how Au works we can we also have limitations in terms of The Branding as well yes we can configure the appearance the way we wanted to but we need to be okay with whatever we get outside of clerk in terms of the look and feel of our application the other trade that we have to make is that because we are not managing the sessions or the tokens or any of that stuff and clerk is doing all of that for us it's also going to manage the users too this means we will not NE necessarily have full control over our users versus clerk is going to do that that means you're going to pay for the number of users that application has so this makes a lot more sense clerk makes a lot of lot more sense for Enterprise applications because the more users you have the more expensive it's going to get and that's how the model works as well one more disadvantage is that if clerk if clerk faces any disruption in their service this means the authentication is not going to work and users won't be able to log in or sign up in your application so you're pretty much relying on clerk to make sure that they're always up and running otherwise none of your logins or sign up are going to work so that is definitely a risk that you need to consider when it comes to using clerk but overall if you're really happy with someone else managing your au and because it can get really complex as I mentioned earlier then clerk is definitely a really good solution and a lot of companies are in fact using clerk these days it's a really good option for you if you're okay with any of these trade-offs so when it comes to odd there are essentially two different ways of storing user information and authenticating a user one of them is session and the other one is tokens tokens would mean Json web tokens or also known as jot or JWT they allow you to verify and generate tokens and that is something that the client the browser use and there's a secret key involved so that the server knows how to decode the token and get the necessary information as well so for example this is how the token looks like it has a header payload and a signature which only the server would know to basically decode the specific token now the client is essentially going to store the specific token onto the browser and that's how jot tokens work in summary but on the other hand authentication also has sessions and essentially sessions would mean that again the server would create the session once the user logs in and gives back a session ID which the client would essentially use to store and authenticate the specific user now again these are two different ways of authenticating users when it comes to Luci o it uses sessions to essentially authenticate the user and with this Au Library we all we need to do is make sure that we get the users information and it's going to abstract away the complexity of handling sessions all we need to do is create the session provided we give it the user ID and then validate the session giving it the session ID and this way we are able to authenticate the users and that's exactly what we're going to do with Luc so let me give you a quick walk through of the luciad demo app that we are going to build so this is the homepage app will be called Au explained let's zoom in a a little bit now over here because we are not logged in it says hello you need to log in with a login Button as you can see this app has a theme thanks to Daisy UI for all the components we will be learning you will be learning all of that too in this specific video then we also have a really nice nav bar when you click on sign up it takes you to the sign up page where you can create an account or you can go back to the login page where you can login so so now let's just go ahead and sign up so now what we are going to do is we going to create a account called as Gobi bean and then I'm just going to ask my browser to suggest a strong password then let's click on sign up the minute we do that we get redirected to login because we have been successfully signed up now ideally it would have been nice to have some sort of a popup message that hey you have signed up but that's optional because we are going to focus on learning Lucia a and Clerk and all the different authentication principles in the specific video so now that we have signed up we are also going to use mongod DB to store all our users and also sessions so if we head over to let's say browse collections you can see now we have the odd database with the sessions table and also or I should say a sessions collection and a users collection now when you when you click on users you can see now that there is a user called as KOB Bean right here with a password hash and an ID created similarly if we head over to sessions then we should also have a session then we should also have a session for that specific user so for example if we take a look at this specific ID the session is also going to be the session with an ID of that so that means we have successfully signed up now let's go ahead and log in using KOB Bean for example and let's H sign in the minute we do that look at that we get redirected to the homepage and now hello Kobe Bean with a sign out button has showed up here this means that we are also able to retrieve information from user profiles and we can show that onto the homepage as well now if I hit sign out then we are automatically signed out and if I refresh the page or let's say go to homepage for example then it says you need to log in so that's exactly what we will be building with Luci so now let's go ahead and set up Luci o and for that we are going to create a brand new project again it's going to be a next year's project as well here we're just going to paste what we copied and then let's call this explained Lucia again go with the default options and then install the dependencies and the dev dependencies now if we go to the documentation for Lucia let's just make sure we install the specific package called as Lucia which is pretty straightforward right here whoops not here but in O explain Lucia let's paste what we copied and install Lucia right here now in addition to this there's one more thing we are going to install to for verifying passwords but we will do that a bit so now let's go ahead and start up our development server if you go to Local Host 3000 then next year with Lucia is ready to go so now it's time for us to essentially get started and import Lucia in our project and create our now let's take a look at this diagram that will describe what exactly we are going to do next first we are going to store all the information about the users and the database now keep this in mind when we were using clerk we didn't need to do that because clerk does it for us but when it comes to luciaa we're going to have access to all our users and maintain the sessions and whatnot as well so for this we're going to use mongodb to store information so in a mongodb database we are going to have two things one we are going to have a session collection and then we're going to have a user collection as well session collection will store any of the session IDs that we would create to authenticate the user and user collection would store the username and password or any of the information that we need about the user in this case it's mainly going to be just username and password now once we store the information inside of our database here's what's going to happen once the user logs in we are going to check if this specific user exists in user collection or not if they exist then we're going to get the session ID right here so I'm just going to say yes this user exists no this user does not exist so if the user exists then we are going to get the session ID and create a session cookie but if the user does exist then we just going to create a brand new session store it in our session collection and then create the session cookie now again all of this is really important for us to log in on the other hand let's say the user signs up then we're just going to straight up go to creating a session for example in that case we're just going to go directly to this specific option where we are going to essentially just create the session and then create the session cookie that will be used to authenticate the specific user so that's exactly how Luci o Works Luci o already gives us the API needed to create the sessions and whatnot but we definitely need to set up our database so let's do that so now let's go ahead and sign in or in your case sign up if you don't have a mongod DB account so let's go ahead and sign in and here I'm just going to enter my username and password and then log in because I already have an account now the way mongod DB works is that you would need to essentially create a cluster as a start in my case I already have a cluster so I'm going to show you the configuration I chose you want to click on shared and go for the free forever option to create a free pricing model for mongod DB so you're not paying anything out of pocket in this case once you do connect and create the cluster you can connect it go to the drivers install mongodb and get the connection string needed to connect to the specific cluster but before we do that I want to show you the database section now when you see cluster you can also click on browse Collections and this is where you would retrieve all the collections we need to set up so for example in this case I already have a OD database so we can just create database and here you want to select OD and the collection name you would want is users and then sessions after that I already have both here you have a user users's collection as well as the sessions collection and that's exactly what I showed right here we have the session collection and the user collection that's exactly what we have set up in our mongod DB as well so we will be storing the sessions here and all our users with username and password here this is the setup for mongodb so all we're going to do right now is head over to overview connect to the cluster go to drivers and then grab this string for getting the database UR L strings that we are going to set up in our application so now let's me just open it up in Visual Studio code which is going to be the editor of my choice and let's go ahead and restart the server as well so right here we have the app and here in we are going to create a new file called as n. loal and this is where we are going to store the URL that we just copied so for example we're going to call this mongoor URI and then paste the URL that we just copied this has all the information needed this urri has all the information needed as possible now you want to make sure that you fill in the username and password here that you would retrieve after you get the cluster in my case I'm just going to paste this information as well now make sure you create your own and don't copy mine because I really don't want to blur my database but make sure you create one yourself because it's completely free of charge as well be are going to now connect with our database and for that let's just head over to the luciia docs and head over to the database section for mongodb here we're going to install the mongodb adapter for Lucia as well because again we need the adapter so that Lucia can know how to connect to mongodb and store the sessions and users that we talked about as well again let's restart the server so now let's go ahead and test our database connection and set up l in that project we have some code here so we're just going to pretty much copy this now what we're going to do is let's create a new folder here called as lib here we're going to have two files .ts file and db. DS file now in db. TS file we're going to store all the database stuff so for example we're going to connect to the client and then connect to the DB keep all the database stuff here but then when it comes to using an the adapter let's move it outside this file's job is to make sure that the database is connected and all the user collections are set up as expected as well so instead of calling this we should call this session doc here so there was a bit of a typo there in their documentation we have the user let's call this collection session collection to make it a little bit more verbos similarly let's just export it because we're going to need that in the other file too now we have the client and here is where we would use our URI so we're going to say process. n. mongoor we also need to make sure we have two more things one is the username that the user is going to enter and the second one is the hash password so we're going to add that over here as well so you see username is going to be string and then hashed password is also going to be string we're going to Hash it later on but for now let's keep it as is session doc will have the ID expiry and the user ID so that we know which session was Associated to which user so for example this user ID is going to be the exact user ID that we use in the user doc now this is complaining so we can just move this inside a Asing block over here just like that or I guess here something like that this way it's going to connect to the database and then give us the database that we need and we're going to make sure that this we need to export this as well now this is pretty much good to go we have our database set up we can get rid of these two items now in our o file is where we would create the new instance of Luci so we have the database here if we head over to the getting started section you want to initialize luciia by copying here and to paste this and we don't need a SQL light adapter we basically need our DV adapter here so so if we head over to the database let's see what we have for mongod DB so we're going to get this specific adapter here and move that here and this mongod adapter is going to come from the package that we recently installed and the session is going to be the session collection from DB and user is going to be the user collection as well now there's one more thing we need to do which is that right now we haven't specified which DB we want to connect to because in a cluster on mongodb there could be many databases so here we're just going to call this I want to connect to the a DB that we created and then basically retrieve the collection from there all right so now we have this and all righty so now we have the session cookie here initialize the Luci adapter here and we only want to make it secure when it's https which is in production we need one more function which is called as get user attribute so we could retrieve the username as well going to have this return and username is going to be attribute . so this is the app that we are building all explained for Lucia now we need a header login and sign up at the same time we need a login and when you click on sign up we need to create this as well so how about we go ahead and install Daisy UI inside of this application as well so that we can design it and make it look like like this one so again let's go to the installation section copy this and install Dy UI now the the theme that we're going to use for this one is going to be cupcake so let's just copy this right here head over to tailin config file and then paste what we copied and this just going to be cupcake as a theme we have our base Local Host 3000 here which is fine so let's go ahead and create a new folder called sign up and this folder will have a page called sign up now I'm just going to say default function page that's it so now we're going to just have a div here and this div is pretty much going to be Flex column it's going to have be centered right we want everything to be centered onto the page and then let's give it a gap of 12 now let's also give it a header here and just to make sure that our theme looks as intended again let's disable the inline fold for this specific workspace so we can see our styling so we're going to say create an account perfect so now if I head over to Local Host SL sign up we see a create an account now let's just go to Global CSS and get rid of The Styling that we don't need essentially right here now you can see create a sign up create create an account right here now if we go here let's just go ahead and create a basic form now let's see if Daisy Hui has something like that so if we go here and search for input let's see what form they have for us so we have a form which is something like this so we can just copy this now all we need is username and password so I'm just going to copy the last two elements perfect so now let's wrap this up in a form and then paste what we just copied now if we go back to not this one but this one you can see that now we have a form as as well as we have a password and a username now all we need is a button here so let's just add that too so we can say button and then sign up now let's make sure we copy The Styling of the button so we need Prim button which is going to be button as primary so let's just copy this and paste it over here as well so now if we head over to this we have Lucia o as this similarly we need to line it so we can say Flex Flex call Gap is going to be four so we have the labels oops put the button inside a label when it should be outside perfect so now there is some spacing here with the sign up and ideally what we would want is a curved border for example so like let's see if Daisy UI has something like that for input so we need something like this with an icon inside so let's just copy this and get rid of all of this so we have not added DIY UI as a plug-in here so we need to do that otherwise none of the styling is going to work and now look at that so much better because we did not add The Styling here so that's what we want to do for sure so let's go ahead and also a padding top of three Ram so it has some padding on top here and lastly let's also give the form a border so let's just wrap this up in a DI div and then for this specific div let's give it a border so again we can say Flex item Center justify Center so in the center of the page Flex column gap of 10 border two border dashed and then give it some padding make the borders rounded give it pink of 300 perfect and now look at that our form is looking so much better and this is going to be the signup form so now what we want is the minute we enter the username and password in this form and when you click on sign up it should sign the user up that means in our mongodb database in our mongod DB database here we should see a user created with that specific username and password available for us so that's what we're going to do now signup form is looking pretty good so it's time for us to connect that with server actions so what we're going to do is all the server code that we are going to write for example to sign the user up to connect to the Monga DB and to check if the user exists or not all of that can be done in a server action there's no need for it to be on the client side that's what we're going to do so in order for us to do that on the form we're going to add eight attribute here called as action equals sign up action and we also going to create a new folder called as actions now here we're going to call this signup action. DS make it a use server so it is a server action file and then here let's just export it export a saying function sign up action and that's it so now what we're going to do is the first parameter is going to have access to is form data which is going to be of the type form data so let's just log form data for example right here now going back to sign up let's just import sign up action from sign up action file that we just created so if everything works as expected let's make sure that there are specific IDs for username so we're going to have username as ID and name username as well same thing for password we're going to have let's not add value to any password so we're just going to have ID as password and name as password as well so this way form data is able to retrieve the username and password from these inputs all righty so now if we let's just enter an key and some password here for now we hit sign up let's clear this just to make sure hit sign up go to action s just say form data so now let's go to anky and add 1 2 3 4 it sign up and you can see that we have a form data with username an key and password is 1 2 3 4 which is exactly what I type so that's pretty nice that our server action is hooked up so now let's go ahead and retrieve username and password from the server action as well so here we're going to say username is going to be form data doget username password is also going to be something similar and we we definitely need to have some validation here for username as well as password so if the type of username is not equal equal to string we don't then we're just going to return it an error for example let's say error is going to be invalid username similarly if the password is not string we're going to say invalid password but again you can imagine that there are more validation messages more validations here such as username do length has to be more than three characters similarly password to should be more than three characters obviously now we also need to make sure that the password length also needs to be less than maybe maybe it should be less than six characters as well you know so it can only Max six characters but again we can add a lot of validations for username and password for now we're not going to do any of that we're just going to focus on focusing on Lucia odds but you can imagine that you can add whatever validations that you want for username and password Here For example so now at this point our username and password is meeting the criteria so now let's just hash the password to store it we need to Hash it then we're going to insert the user in user collection because in our database for example then once we do that we can create the Luccia session and then set the cookie in the browser once everything is successful let's redirect the user to log in to sign up so after success so this is what we're going to these are the steps we're going to follow right we now have the username and password we're going to Hash the password we are going to insert the user in database we're going to create the Luci Lucia session we're going to set the cookie and also redirect the user to login page because they have successfully signed up so all of this makes sense and once this is done we can move to log so in order for us to Hash the password I don't recommend you to implement any hashing algorithms from scratch but instead use a package called as argon node RS argon now this essentially allows you to Hash the password in the most secure way pass possible and it's going to take away and handle the complexity of making sure that our password is successfully hashed as expected for example so now if we go to the Argon 2 package for example the Argon 2 was also the winner in the password hashing competition as well so how about we just go ahead and install this let's npm install Aron 2 and now we have Aron 2 so let's just go ahead and hash the password the function we're looking for for hashing the password is going to be hash from argon so we can just say await hash which comes from argon 2 we are going to give it the password that we got the string password and here is what we are going to add as parameters we're going to make the memory cost as 1 194 85 time cost two output length 32 and then parallelism is one now we can go ahead and read all of those for example over here memory cost is going to be the amount of memory used in the hash function time cost is going to be the amount of passes used by the hash function it increases the hash strength so we're going to say that we want it to be two and then output length is default is 32 so that's what we're going to do adding the output lend is 32 and then the last one is parallelism which is which means the which means that the amount of threads to compute the hash on again it's it's going to create the most secure hash possible so that no one can decrypt the password so now we don't even need to add both of these here because by default it is 32 and one but you get the idea we want to make sure that we are creating a really good hash now we're going to get the user ID here now we're going to say generate ID from entropy size ID and we're going to give it a size of 10 we're going to create a user ID for example which we are going to use to store in database the our password is essentially going to be hashed right here so now let's just make sure it's actually hashed as expected if we head over to our application hit sign up go back here you can see that it's enabled to parse it's unable to parse the specific character and for that reason in the next config file we need to add a specific value so we're going to make it experimental we're going to add a server components tag which and we're going to add no RS argon to package here because for some reason nextjs is unable to handle the specific characters so again we're going to restart the server because we made some changes now if I click on sign up you can see that we are able to we don't see the hash password so let's just sign up we see the form data but we don't see the hashed password so let's see hash password this let's just make sure that the password length is greater than three which we do have it and username is more than three I hope it doesn't return an error so let's just add a console log [Music] here so this should be the opposite that's a mistake we made and same thing over here as well now let's go ahead and try it out if you sign up we should see the hash password as expected and it has the Aron 2 ID and some other characters which we don't really need to care about it is hashed successfully all right so now we have the hash password as well let's also add one more validation to our password which is that the length is going to be greater than 255 that means it's invalid password and here let's just add invalid password invalid user user name perfect so now we have some validations we have hashed the password so now let's just go and insert the user in the user collection in database so now let's go ahead and insert the user in our user collection so here we have the user ID created but we're going to do is we're going to use the user collection that we created and insert one value which is we only want to insert one specific value user ID is going to be the Lucia ID username is going to be username and then password hash password is going to be password hash now these are all the values we want to add and ID does not exist but let's believe it's underscore ID which does exist I go to user collection it is underscore ID perfect okay so now we going to insert the user so if everything works as expected before we even create any of this it should create insert the user so now if I click on sign up we get an error never we get an error saying that it cannot read properties of undefined so let's make sure everything works as expected and we made a mistake there is no URI so let's just run the development environment again refresh the page let's call this anky with SS password and hit sign up minute we do that looks like it worked if it did we should see a new user in the database so let's see we have an anky user but it's really hard to tell because we already have so many users here so let's just go ahead and delete all of them okay so now let's go ahead and try it out again so if I click on sign up and if we go to mongod DB all users and look at that user has been successfully inserted which is what we want so now the next step in our server action which is the signup server action that we have is to create a Luci session now in order for us to create the session all we're going to do is again use luciaa to basically create the session that we want so we have that we're going to pass it the user ID and the second parameter can be empty so this session creates the session with the user ID that we get that we have generated here which we inserted here and then we're using it to create this session in Lucio now we need to create a cookie so that we could store that inside the browser so again we're going to use Lucia to create a session cookie and this session has an edit return returns a session type which has an ID so we're going to do that we're going to get the session ID from session and then use that to create a cookie and lastly we're going to use nextjs headers to basically set the cookie now session cookie is going to have its a name a value and also whatever whoops whatever attributes as well so we're going to say attributes right here so we are setting the cookie right here and if everything works as expected we want to also redirect the user and redirect comes from navigation to login now let's see what happens so if we go back here hit sign up we are redirected to login that means everything works as expected so now if we go to in browser developer tools go to application and then after that let's head over to cookies we see a session cookie here but again not good enough for us cuz we don't know what was there before so let's just create another one so let's just use my dog's name Kobe hit sign up log in you can see an odd session cookie did get created which wasn't there before so that's exactly how you would sign up a user now I recognize that we don't have any logic here to check for an existing user first before for signing up a user but we don't need to worry about that for now let's just make sure that whoever is signing they are signing up for the first time and you can add the logic if you want to extend the specific alt layer to basically check if the user exists or not but we don't need to do that right now all right so now it's time for us to build the lockin page so just like we buil signup just like we had create an account we also need a login page as well login and sign up are very similar as you can see right here the only difference is title so we can pretty much copy the sign up page we have create a new route called as login and we are going to create a new page DSX and paste what we copied instead of creating an account let's call login with a lock sign and instead of sign up action we going to now have login action let's just create an empty file here called as login action. DS again it's going to be a server action as well but now we don't need to literally worry about it we can keep it as is there's nothing in there so let's create a simple function and then let's call this login action and import it right here okay so now we have username we have password and instead of sign up it should be sign in okay so this is the not our app this is the app we have we now have a login page which is pretty awesome we have the username and we have the password if we add value here value is now empty so now we can add this and ideally what should happen is the minute we give it the user that already exists in the database it should be able to log Us in so that's what what we are going to do now so now in the login action similar to what we did earlier we're going to log form data just to make sure everything works as expected go back here hit sign in go here you can see that we have the Kobe and password is just literally password super secure so now let's go ahead and build our login server action here so again like we are doing for everything else what we is essentially need to do is very similar to the signup action we need to get username we need to get a password we don't need to Hash it though because that's already been done for us we're going to say that hey if type A String we're going to give it the same error messages for example as well but then we're going to check for existence does this user exist if it exist and in the database is what we're going to check then when if the user does exist then we need to verify password because just because the user name exists does not mean that the password matches because I could pretend to be someone else and that could lead to malicious attacks which is not what we want and we're going to use ver password using argon as well because again we want to make sure everything works and then we're going to create a session if every everything works and we're going to pretty much repeat what we did here we're going to create the Lucia session then we're going to set the cookie in the browser and then we're going to redirect to home in this case so first let's check if the user exists in the database or not and for that we're going to use the user collection like we did earlier so so first we're going to check if the user exists or not and for that we're going to check if the user is an existing user and we're going to use the user collection find function and we're going to pass in the username here because if it does if the user does not exist then we just want to say hey there's an error incorrect username or password we don't want to give it we don't want to give malicious users what is wrong with their with their specific entry we just want to be very vague about it incorrect username or password but let's say the user does exist and in that case we want to check if it's a valid password or not for that we're going to use the verify function from argon we're going to give it the existing user. password that we have we're going to give it the password and compare it so you want to make sure that the existing user whatever is in the database and the password that the user entered matches and we need to give it this the same algorithm that we did earlier so we going to give it exactly this value so now if it's not valid then we can again give it the same error saying that hey the password is not valid CU again don't give any information to the users but if it's valid then we want to do exactly what we did here we're going to create the Lucia session and we're going to do all of this that we did earlier so we can create here let's import Lucia here user ID is going to be existing user doore ID because we already have the existing user we're going to get the session ID from Lucia then cookies is going to be from next headers now that we have all of this information we're going to again redirect the user imported from next navigation and redirect to home this way we know that everything has worked as expected so now let's test it out so we have Kobe as a user we know that Kobe is ex existent in the database and we can double we can make sure double check as well right here so we can click on users and we know that Kobe exists so now let's sign up using Kobe and if you hit sign in there you go we have been successfully logged in into our account as expected so in terms of of login actions we don't necessarily need any of this same thing in our signup action so in terms of our login action all we need needed to do was verify it using the same hash algorithm that we provided create a Luci session create a session cookie and then set the cookie now if everything works as intended then if we go to our cookies inside the browser developer tools we also see a odd session which is pretty awesome now on the homepage we literally have this we don't even need it we can pretty much get rid of all of it because here what we need to do is we need to verify if the specific user is valid or not if that's the case then we need to just redirect the user somewhere else so for example we need to check if there's a user that exists we need to call create a new function called as validate request if there is no user then we need to just redirect the user to/ login because the user is already logged in so let's turn this into Asing function but before we do that we need to style it so now again let's use the same styling here and then let's create a div and then this is where we would have our user so here we can say text 3XL capitalize so here it's time for us to access it so we can say if user. user. username then it exists otherwise we need to say you need to log in frankly we won't even reach to this condition because of this but let's comment this out for now so now let's go ahead and implement this validate request function so that function could exist in our o Library here we can create a new function and call this validate request now in validate request we want to check again get the cookie from our browser developer tools in the cookie section validate that specific session is this a valid user if so then set the cookie refresh the cookie essentially right so what we're going to do here is say validate request equals cach we're going to cach it in the the react function then we're going to say this is going to be a async it's going to return a promise and it's either going to return a user or it's going to return a session or it's going to return user as null because if there's no valid user or it's going to return session at as null for example now let's write some code here so first let's get the session ID we're going to get the session ID from cookies. getet luag doget not user session but session name session cookie name and get the value otherwise it's going to be null if there is no session ID then just return what we talked about here user is null session is null but let's say that if it does exist then we are going to have a result and we can validate it using Lucia so we can say validate session with session ID and this us is going to validate the session and here it's going to be there you go now once Lucia validates the session we need let's put this in a TR catch Block in case of any errors here so here this is what we can do if there is a session and if the session is fresh then what we want to do is create the cookie here but if that's not the case then we can just create a blank session cookie so we can just say Lucia do create blank session cookie and then cookies basically we are going to nullify if anything that exists do name we already have this here so we're going to just copy this perfect and then we want to make sure that we are returning the result here now we want to create the cookie here so again what we could do is similar to what we had earlier we're going to create this get the session cookie so instead of session cookie create session cookie it's going to be result. session. ID and we are going to set the same thing again because we this time we actually have it so this is going to help validate it if the Val request is valid or not so we can uncommon all of this and we're going to say let's validate it let's get rid of this as well all right so now if you go back and if we go back to home see how we are get getting navigated back to home so let's delete this let's just log in with Kobe cuz we know that exists and the logic is incorrect here so if there is no user return to login so now let's just log in with Kobe sign in and look at that we get username Kobe here now all we need is hello Kobe because that's literally what we have here so and this exactly the application that we are building here too we have the Au explained header with sign up and login values all righty so now in order for us to make the navigation easier let's just grab and paste this in the layout all we're doing here is we are setting the header to be a explained we are creating a sign up and sign in link and now let's also make this route to home as well as we do that if we go back to our application you can see Au explained has hello Kobe here if I go to log in or sign up I'm able to do that but in reality what we want is once the user is logged in or sign up then if the user is already logged in we don't need login or log out we don't need need login at all all we are going to need is log out so that's also something that we can Implement next there's one more functionality we need to work out which is that if the user is logged in which it is in this case because we seeing hello Kobe then they should this login should turn into a log out that means if I go back here in the layout we have sign up and sign in or if we go here on the homepage right here then we should be able to log out here as well for example or if we go to layout then we should be able to log out here as well because right now it says login so we need a similar logic of homepage here which is the validate logic so if we go to layout and paste this let's make this amazing function and then validate request and redirect the user for example this way any user will be redirected now similar to what we had here that hey if the user does exist so what we can do here is we can keep sign up as is but if the user exists then use this as an Li else let's create a simple form with a action some sort of an action and then a button which says log out right there so now here we can have a log out server action but for now let's just commment this out so we should see log out here if we have everything works as expected so if user. user exists then it should be the opposite and the form should go here perfect so now you can already see that the log out does exist which is what we want now let's give it a class name of button button Prim memory and hover is going to be BG purple 600 this could be a nice log out button here for example same thing for the link as all righty so now the design can we can fix that design a bit later but we have the login and then we have the log out here now let's create the action for it so we can say action equals log out action so let's create a new action here called as logout action. DS going to be a server action it will have a very similar signature right here let's call this log out action you go to layout let's just say log out action perfect now we have the log out action here we're going to use exactly what we had here which is that we're going to need the validate request function which is going to validate if the user is valid or not we can retrieve the session from it and if we we're going to say if there is no session then just return redirect to be at login we don't want to to deal with that but then if there is the user is logging out for example we are going to use the inval we're going to import Lucia we're going to invalidate the session of the user with that specific ID as well this way we we want to clear everything that we have set up so far we don't need anything here similarly for session cookie let's just create a blank session cookie so we can clear it all out similarly we just need to grab all of this what we had here you're going to we're going to clear everything out there you go so that's exactly what we need so now if we go to our developer tools and go to cookies we have all of this the minute I click on log out you can see that the odd session is gone and we have been redirected to log in which is exactly what we're looking for now I know that we added this in the layout itself but we can pretty much move this elsewhere so this way sign up and sign in can stay as is so we can just copy this entire thing and let's just move this back to login or sign in there you go and then here we can just do this log out action and this can be outside the pag also the div so we have the sign up and sign in if you want but at the same time when we go back to home it says hello you need to log in and we have the login option here we don't need an unnecessary lii here if I go back to home it says hello you need to log in but there there's also an option to just hit login and just log in as well so yeah that's exactly how simple Lucia login is and we have implemented so much in Lucia from scratch but because of those helper functions it made our life so much simpler with this Library so which one is exactly your favorite in terms of all the art libraries out there do you think you're going to go with Clerk or do you think you're going to try something like luciia which is really awesome so let me know in the comments below what you're looking for next and also what you think about these libraries and is this something you would give it a shot in your next project while implementing authentication so that's all for this video bye F now
Info
Channel: Ankita Kulkarni
Views: 3,101
Rating: undefined out of 5
Keywords:
Id: uSIm5Uzub60
Channel Id: undefined
Length: 92min 33sec (5553 seconds)
Published: Fri May 24 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.