How I Authenticate my Sveltekit Apps

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
lately I've been using and loving Lucia for the authentication step for my spell kit apps I've had a great great experience using it and today I want to go over how it actually works I built out a nice little example application that showcases email and password authentication we're going to go over that later in this video I have a full example repo built out for this we're going to clone the repo run it from scratch and I'm going to show you guys how all this stuff works step by step but before we get into that I first want to talk about how this actually works in theory so we're going to start at the high level at the diagram stage now different off providers work differently some of them will handle more than others Lucia I would argue it feels to me like a very light abstraction on top of custom rolling your own authentication it's pretty close to the point where you need to understand what's really happening for your authentication system but it's not close enough to where you have to do the annoying stuff like inserting into your users table and all that stuff it'll handle a lot of that for us but it effectively just provides some really nice helper methods and systems and adapters and stuff to get authentication rolling quicker and easier and better while still giving us a ton of control so I know that probably didn't make a huge amount of sense so let's first jump into this diagram and also one more thing I do want to disclaimer this this is not going to be a full Deep dive into all of the different things Lucia can do there are going to be some edge cases and different things that we're not going to quite go over in this video this is very much meant to be a highle introduction on how this stuff works get the example app downloaded and running get it so that you guys can actually use this in your apps and then later on we'll probably do another video where we get super deep into the nitty-gritty we do ooth we do other stuff like that for right now we're just going to do the super high level barebone stuff so this right here is a very highlevel visualization of the data model that Lucia requires Lucia requires us to have a database backing our authentication system and it wants us to create these three tables it wants us to create a users table a keys table and a sessions table starting with the users table this is by far the most like obvious and simple of them all this is just where we store our users this is where we'll put their user ID which is going to be the primary key that these two are referencing it's where we can add more optional attributes and data so like in the e-commerce site we're building out this is where I can put stuff in like the stripe customer ID I can put in their email first name last name their address all these different things we need we put that into the users table these are the two that are more specific to Lucia well they're not specific to Lucia most auth communication systems use these but these are the two more complicated tables so we'll start first with keys because keys are this is the thing that took me the longest to sort of get up and running and understand within Lucia but they're actually really intuitive and really really nice so what keys are is keys are effectively a reference to the user you'll remember when I was telling about the user table I didn't say anything about the user password or their GitHub ooth information or whatever different authentication system we're using those are actually keys this will make a lot more sense when we actually get into the code of how all this works but these keys are effectively think of them like the passwords or the I mean I don't want to use the name in the definition but I mean it really is kind of circular that way these are the keys to authenticate our users this is where we'll store an email key where we'd have the provider id being the email then the provider user ID would be their actual email then the password would be their hash password so that system allows us to go through and when we authenticate our users we use the key we go through all the keys with the right um system so we go through all of our email Keys find the one that matches the data that's provided then if it matches we can then authenticate the user so I know that probably didn't make a huge amount of sense but we'll get more into this in a second then finally we have the sessions the sessions are the actual things that allow the user to authenticate into your app whenever the user authenticates into your app it will create a session which effectively just is a reference in our database to say hey they're authenticated on this device and when the users stores that session ID we can uh verify that session ID within our database to be like yep you're authenticated your session is valid not expired and we'll let them go through so this is just storing the user sessions this is storing basically the users passwords or their credentials for ooth or whatever that allows us to authenticate them and this is storing the users themselves so let's look at how this actually works you know normally when I do these videos I go and I already have the repo downloaded I already have all this stuff set up I want to take you guys through step by step how you would actually use and reproduce this example because I want you guys to actually be able to use this cuz that's the only way it actually does anything obviously so what we're going to go ahead and do is I'm going to go ahead and clone this um this is not a GitHub tutorial or anything like that uh so we're just going to clone this in here cloning uh we'll clear this out and then now we have our spalet Lucy example so we've got our project cloned from the GitHub this is what you guys will actually go through and do yourselves and then once we get this opened up in vs code there's really not too much we need to do to actually get this running but I do want to show you guys those steps uh so that you don't have to figure them out yourselves so the first thing we're going to do is go into our env. example and copy this into an actual EnV file uh this project is very simple and lightweight all we have here is just a database URL so we're just going to paste this database URL in here you'll notice that it's a file local DB that's because we're going to be using sqlite for our database more specifically lib SQL and turo because I'm really I've been really enjoying using turo lately it makes a lot of sense for my projects and it makes a lot of sense for the sort of um it makes a lot of sense for my projects and it's a really nice simple quick easy way to get this stuff up and running so we're going to be using a local database here in sqlite and now all we need to do is create our database so now that we've got ourv created we now need to go ahead and install our packages I'm using pnpm I'd highly recommend you guys do the same uh bun is also really good I'd say either bun or pnpm I use pnpm because I have so many freaking projects on my disc drive because of all the videos I make and stuff to where having that reuse of packages is huge because I don't want 20 terabytes of node modules uh but if you don't have too many projects bun is a great alternative so we're going to run pnpm install once we've done that there's one more thing we need to do within our package.json here you can see I have these two extra scripts called uh DB push and DB Studio the first one we're going to run is DB push so we'll do pnpm run DB push what this is going to do is this is going to generate and Seed our actual database so when I run this it'll run a bunch of stuff drizzle will some magic and you'll notice right here we have this local. DB this is not a drizzle tutorial if you're interested go check out their documentation and also you can see within our drizzle config we're pulling out our schema from this directory and then we're going to go ahead and use the database credentials of just a local database so using this config we're able to create our little local database so now that we've created our local database we can go ahead and run pnpm run DB studio and we're going to go ahead and use um I'm going to go ahead and showcase drizzle Studio here again this is an a drizzle video but I think it's really good for you guys to see how all this works and this will be very helpful for explaining everything later so you can see in here we have our users our user keys and our user sessions so all that's set and done and ready uh the last thing we're going to do is I'm going to open a new window we're going to do pnpm run Dev this will spin up our local spell kit instance we can do this let's go to um Local Host 5173 give it a second to load and compile and now we will get our very mid de Dem Mo all done and ready so now that we've got this I think we're ready to go over how this actually works so to begin let's talk about the data model the data model here is really simple it's like what I went over at the start with the highle explanation um all we have our three different tables we have our users table which stores our users information we have our session table which will store the actual live user sessions which will allow them to stay authenticated into our app for a long period of time then fin finally we have our keys and these keys are the things that we will use to actually authenticate our users into our apps so their user ID will be their email then hash password will be their actual password so this is just the basic stuff for Lucia you can get all of this out of their documentation which is linked below it's super simple stuff so now that we've got this all set up and ready we need to initialize our Lucia instance so you'll notice in here I have my index.ts for my database all we're doing here is creating a lib SQL client and we're creating it uh using our database URL or off token I don't have an off token set for this example cuz it's not in prod or anything but this is where if you were using turo you'd put in their authentication token here again you don't need this CU we're running everything locally so no big deal here our lib SQL client and then we create our database itself using drizzle everything you've seen before uh the only sort of weird thing here is we are exporting our lib SQL client and the reason we're doing that is because within the authentication directory we're creating our Lucia instance so from off I'm exporting reporting an off object and that's going to be a new instance of Lucia we're going to be using a lib SQL adapter here they have documentation for all of this but I wanted to show it in the video because this whole setup process can be kind of a pain once it's set up and going it's freaking amazing but it does take a minute to get set up and it did take me a couple hours of reading and getting everything ironed out to get all this stuff working um we'll probably turn this into a template later I think that could be really really useful um but anyways we're creating our adapter we're creating our Lucia instance we start with our adapter we're using lib SQL so we pass in our lib SQL client which we're importing from our database we then pass in the user key and session what these are is these are actually the names of the tables within our database remember within our schema we were setting our user table to be user our session table to be user session and our key table to be user key these also match over here within the drizzle studio so we're doing all that stuff there so then we want to make sure that within our adapter we're telling it that okay our users table is called users our keys table is called user key and our sessions table is called user session this is just to make sure that everything's hooked up and it can run the database statements correctly next up we're going to do EnV Dev because we're running this all in development that basically just that's for https don't really need to worry about that right now then we're going to go ahead and add this extra thing called middleware for spel kit and this will allow us to do a really cool thing and attach some Lucia helper methods to our locals so we'll show that next so we're setting our middleware to be spel kit and then finally we have this get user attributes by default Lucia will only handle within our users table just an ID it'll just be a floating user ID on a table nothing else added in there so what we want to do is we want to add some more attributes to this to get more information in there so we're going to add first name last name and email now when we go back over to this authentication system remember it doesn't have those by default so we need to tell Lucia hey our first name last name and email are coming from the database user their first name their last name and their email so we're just attaching those in there and the place where all this comes from is going to be our app. D.S So within our app. D.S we need to go ahead and create some extra types for our Lucia integration so we're creating a new namespace called Lucia then we're going ahead and assigning some types so we're going to say the type of O is equal to the O object which we created within uh here then our database user attributes so these are the extra attributes we're adding to our user so that's email first first name and last name and then finally we're adding some exra extra session attributes and I'm just saying object because I'm not actually adding anything into our uh user session I don't care uh you could go ahead and add in like an expiration date or a created ad or whatever the hell you wanted to add but for me in this example we don't need to add anything else but this is where you would do it if you wanted to next now that we have our types created we need to go ahead and look at our actual hooks so for those of you who aren't familiar with hooks these are basically middlewares that will run on every single request so this little handle will be called every single time we go ahead and um this will be run on every single request be it a load function a form action uh API request whatever it is we'll call this handle function and within this handle function what we can do is we can set event. locals. off to be off. handle request event this works because we set up the spell kit middleware earlier so what we can do is we can set our locals parameter to be the handle requests we can set the off parameter to have um the results of this function and that will give us access to a ton of really useful helper methods which you're going to see very very soon here uh then we go ahead and resolve the event like normal and that's about it so that's the core of the data model and setup for this app it's really not too diff terribly complicated it's just kind of a pain figuring out where all these things go but once you have it in hind sight and especially when you have an example should be very easy to work with now let's take a look at the actual front end in the actual implementations of all this stuff when I hit sign up or login it'll take me to this really basic sign up page I um you'll notice that this looks a lot better than my demos usually do they usually look really really awful and the reason is because I'm using Shad CN for spelt it's not going to be the focus of this video but we will be coming back to them later so yeah definitely keep an eye out for that another thing that I think is pretty cool about this system is when you hit login it'll take us to the login side of things and we can switch these two out really quickly and easily but you'll notice up here here I'm actually switching the URL so I have the signup page and the login page and what makes these work so freaking well and this whole system be so cool is I'm actually utilizing layouts within spell kit I have a video on this that I just made but basically all we have to do in here is within our off directory I have uh login and sign up are two different pages within this off directory and they're United by this layout. spel so This fancy little picture I got off unsplash to make this look a little more confident um you know um so this nice little picture here is just being put in Via this div and then this slot is where the actual page goes so all that's actually happening on the login page is all we're doing is just printing out this card and all we're doing on the signup page is we're just going ahead and printing out this cards so really cool fancy routing stuff you can do with spell kit highly recommend you guys check check that stuff out and figure out how you can Implement that into your own apps super useful for like dashboards and stuff like this uh but regardless with all this set stuff set up let's go ahead and sign up a user so we're going to go ahead and here we're going to do Davis actually I don't want to put my real email in go ahead and do testing gmail.com we're going to do uh Ben Davis and for password we'll just do password I don't have any um like password authentication stuff on here so it doesn't matter what the password is in production you should actually set it to matter um but once we fill out this form we're going to go ahead and be able to hit sign up with email and then that's going to go ahead and create our account and sign us in So within our uh signup page we'll start on the client uh it's really simple we just have an actual form uh the nice thing about spell kit is we can use forms the way they were intended to be used so I just went ahead and created this really basic form here it's going to have a method of post because we're going to be utilizing the form action within our page. server. TS here uh I'm just getting their email first name last name password confirm password I have down here I can check if there's an error message because this can be returned from the form itself and then you hit sign up with email and it will submit the form so really nothing particularly crazy down in this section the cool stuff happens on the server so when we go to our page. server our default form action is where we're going to actually sign the user up the first thing we're going to go ahead and do is pull out the form data make sure it's valid and then yell at them if it's not I just made a very quick video on this I'll link it down below and basically all we're doing is we're using uh Zod form data package to validate our form data I know you can use like super forms and stuff like that I have not tested those out uh for right now this has been working great for me but I will definitely take a look at that and maybe make a video on it in the future but anyways with this all set up we pull in our data make sure it's successful then we're going to go ahead and validate that the two passwords are the same their password and confirm password are the same um this should probably also be validated client side but again I just didn't really bother with the UI uh you can easily do that using some basic state variables and checking not a big deal then with all that stuff done we can finally create our user so remember with Lucia we have those three tables off key and session here we're going to go ahead and we're going to say our user is equal to off. create user are we're going to pass in those attributes and then we're going to pass in the key now remember what I said about the keys the keys are like it's email or it's GitHub ooth or Google ooth or whatever we're going to say that the provider for this key is going to be email we're going to say that the provider user ID which is how we identify the user thems is going to be their email address and then we're going to say the password is just what we pass in which is the password that they provided uh we don't have to worry about hashing the password Lucia will do that for us they'll salt hash do all that great stuff and they'll also do it in the other direction so we don't have to think about that stuff we don't have to think about creating jwt's we don't have to handle any of that stuff Luca will do it for us so we go ahead do all this stuff create our password and then once this user is created we can create a session for this user because obviously the user needs to be logged in we go down here we say con session equals O.C create session and this off object right here is being imported from our server off directory we create the session for the user pass in the user ID uh we don't need any extra attributes for our session so we just give it an empty object then the last thing we have to do is we have to set our session so we're going to set some cookies and stuff like that but remember way back when when we set up those hooks we have locals. off now so we can do locals. off. set session session so we're just going to set our session in here and it'll handle everything for us and that's it we are now logged in and we have our we have now created our user and we are logged in it'll uh make sure that it works if it doesn't work it'll yell at you then it'll redirect you to the profile page on the profile page you'll see that I have hello testing gmail.com it gets my email and the way it does that is really really simple all we have to do is within our um within our page. server. Ts for this page what we're going to first do is we're going to validate our session so you can run locals. off. validate that'll give you your session we can make sure that the session exists if it doesn't we're going to throw a redirect to signup and then as long as all that stuff's there we're going to have session. user. ID and we're going to have session. user. email and then now within our page. sell we can uh we can use all this stuff handle it as we will and we've got our account I'm not going to go over all the front end stuff for the sign-in page because it's really basic but basically all we're doing within the signin page is we're just grabbing email password then the interesting stuff is for Lucia down here what we're going to do is we're going to grab their key so remember keys are the identifiers which we use to log our users in we're say off. use key email so we want to get their email we'll set res. data. email and then their passwords we're just passing in their user ID and then their hash password this password isn't hashed obviously but they'll handle all that stuff um then we go ahead and say session equals off. create session user ID no attributes here and then we'll set our session so basically what we did before just instead of creating a user we're just using a key very basic stuff um the profile page we just showed that and then I guess the last two things we can look at are going to be the logout system uh the first thing we need to do is grab their session make sure they're logged in and then after we validate their session we're going to go ahead and actually invalidate that session so this is going to delete the session on the database then we set our session to null so that'll remove the cookie and then we redirect them to log in so now if I hit log out and then we try to go to the um me try to go to the profile page it's just going to R Us redirect us straight back to sign up because we don't have a session anymore so now I'm going to go ahead and log in testing gmail.com password sign in with email and then the final thing I'll show you guys how to do is delete your accounts we hit this button we delete our account we're back to Mid demo and the way we do that is incredibly simple actually I have within the profile page I have this extra server directory we expose a delete endpoint all we have to do is grab session here uh you can actually see I console. logit down here this is what the session object actually looks like uh we go down in here do all this stuff we can go ahead and then just call delete user we just do a wait off. delete user pass in the user ID this will automatically clear out all our keys all our sessions the user object we can send back a 200 of deleted and that's it that is the authentication system done and dusted hopefully that was helpful for you guys I that went a lot longer than I intended it to but you know there was a lot to talk about here and I wanted to make sure that we got deep into it and you guys got a full sort of look at how all this works this is a prerequisite to some stuff I'm going to be talking about very soon within the e-commerce site Deep dive I'm doing uh Lucia is how I'm going to be handling authentication in there and it's how I'm going to be handling it in future projects so I wanted to get this video out there give you guys a good example of how all this works uh again I highly recommend you use the example that I provide down below run through try and actually get it running on your computer do all that stuff and uh let me know if you have any questions uh if you enjoyed subscribe and I will see you guys very soon
Info
Channel: Ben Davis - Tech
Views: 7,019
Rating: undefined out of 5
Keywords: SvelteKit, Lucia, Auth, Database, Drizzle, Web Dev, Develop, Development, Programming
Id: o7qpw6NeFgw
Channel Id: undefined
Length: 21min 31sec (1291 seconds)
Published: Sun Dec 03 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.