SvelteKit + Lucia Auth Explained in 15 Minutes

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today I'm going to show you guys how I implemented authentication into my e-commerce site it is remarkably easy these days to get it set up and working we're using a full stack spelt Kit app drizzle for our database and Lucia for our authentication Library Lucia provides a bunch of really useful helper methods and functions to uh enhance the authentication experience and do a lot of the Annoying TDM of it but it doesn't fully replace everything and we still have to implement some things custom and what's really nice about it is it's not a provider we're not using like Clerk or oero or something where our users are going to go off and live in someone else's database they live entirely in our database so I'm going to show you guys how all of that works if you enjoy this make sure you like And subscribe and yeah let's get into it I am currently using Lucia V3 this is the most recent upto-date version of it uh I believe they're currently going through changing some stuff up they have changed a lot of the way it worked I made a video on this a while ago and I think in that video I used Lucia V2 we're now on Lucia V3 and basically the biggest change there was they removed the keys from the data model and heavily simplified it if we go to our schema. TS and we look at what we actually need for our our users it's really simple all we need is our user table so it's just our user with first name last name provider provider id I'll talk about why I have these in here in a moment um all this stuff is very simple and then we also have our session table right here which is the same thing as it used to be and there's no more like key table there are no more keys to validate the user it's just we store the important information on the user if I supported email password authentication we'd put our hash password in here I don't because I don't like email password authentication I don't want your passwords i' would much rather just use Google ooth and GitHub ooth which is what we're using here so uh I guess I'll start here by talking about why I have this provider and this provider id now uh the way ooth works is you'll obviously sign in Via GitHub or something and you'll get a user ID from GitHub so you'll get like uh whatever your GitHub ID is and then we can use that to authenticate our user so in our database with in our user table we need to store what their ID is for their provider so what we need to store is we need to store okay did they sign in with GitHub or Google so this is an enum we can select either Google or GitHub and then we need to pass in the provider id because this is how we identify the user in our database or because this is how the user is identified from that provider so we have our provider and our provider id and then I set the primary key of my users table to be a uh composite key of the provider and the provider id which that means that it has to be unique and that's basically what our users are defined by they're defined by their provider matched with their provider id I also generate a user ID right here because that's just easier to work with in the relations and stuff uh but their real primary key is their provider matched with their provider id there are a lot of other ways you can do this another way you could kind of do it is you could do like format the user ID as like GitHub uh GitHub vertical bar whatever the heck their ID is or Google bar whatever their ID is and then you would just whenever you're parsing the user and logging them in you would grab you would like create this ID so you take the provider and then match it with the ID personally I thought it was easier and more uh verbose to set it to be provider and provider id so that we know exactly what we're looking at and in the user creation methods you'll see why uh but yeah that's how we're sort of setting up our users and sessions table the setup for this is really not too difficult they have adapters for almost anything you could use we're using uh drizzle cuz that's my personal favorite omm right now so we need to go ahead and create an adapter for this so we're going to create a new MySQL adapter we pass in our database instance which we're importing from our DB or we're passing in our session table and we're passing in our user table and then this way Lucia can go ahead and run the methods it needs to for fetching our users out of our database uh saving them in doing all that stuff we then go ahead down here and imp and initialize our ooth providers this is using the new Arctic Library which is kind of part of the the um I don't really know what to call it CU this is the first time I've seen this but like the Lucia Cinematic Universe type I don't know um but there are like a ton of different packages that are kind of subsets of Lucia I think oo is one of them uh there's a bunch of different packages in here which all kind of do some subset of authentication really well cuz sort of the theme on this is they give you nice tools to help you deal with the annoying crap like implementing ooth without completely taking the whole thing away from you when hosting it in your own database like Clerk or off zero would so what we're doing here is we're creating a new instance of GitHub uh we need to pass in our GitHub client ID and our GitHub client secret uh let me show you guys real quick how to do that it's actually really easy to get these things uh you just go into your GitHub settings you go into your uh developer settings you go into your ooth apps and then you go ahead and grab the stuff in here I believe this is under Rock our glass local that's what sediment used to be called you grab your client ID you create your client secret and that's it that's all we need to do to initialize a new GitHub instance uh Google is a much more of a pain in the ass um you just have to do it through the Google Cloud console grab your client ID grab your client secret create the redirect URL which we're doing by just grabbing the base URL and then redirecting them to off callback Google that's actually a method which we are implementing here if you look over here in Roots slof callback we have a callback function for both GitHub and Google we'll talk about that next um but yeah it's a very similar process creating a new Google instance and then finally we're going ahead and uh initializing our Luci instance so we need to create a new Lucia instance we pass in our adapter which is how we connect to our database we go ahead and check whether or not our session cookie should be secure if it's in production it should be if it's in local we don't care because we don't have https in local then a really nice thing we can do in here is we can grab user attributes for the actual user so if you remember on the user table I had first first name last name email admin and stripe customer ID all of these are things which I'm going to want to have access to on the user object when I grab it and Lucia makes this super easy so we can just Define these user attributes right here return it from this function and now our user will and now whenever we access our user object we'll have access to the stuff and the way we go ahead and ensure that that works with typescript is down here when we're declaring our module Lucia we uh register our actual Lucia instance and we also register our database user attributes we can do the same thing for the session if we wanted to add some more uh metadata to that personally I don't have anything in here but you could put some more stuff in that so the authentication flow here is actually really really simple so I'm going to use signin with GitHub as an example if we go to this page which is uh a login I believe yes it's a login we've got a bunch of stuff in here and then this button right here it just links to off/ login GitHub and this is where the real uh the real work sort of starts so we we go to login GitHub and this server. TS this is going to expose a get request so whenever we navigate the user to this it'll fire the get request and then we can go ahead and set up their GitHub ooth state so what we're going to go ahead and do is and this is all boiler plate code pulled directly from Lucia's docs they have docs on how to do this for all the different ooth providers but the gist of it is we have to go ahead set it up we have to set up the state for our ooth we have to get the URL uh from GitHub and big thing we got to do in here is we got to uh add in Scopes to say user email because we want to get the user's email here so we're going to say Scopes user email then we're going to go ahead and say event. cookies. set the ooth state we'll use this to validate that it's a valid State when they get redirected back to the site in the call back and then finally we just redirect them to the URL that we set up so we're going to go ahead and do that I'm going to hit sign in with GitHub I think I'm already logged in here so yeah it'll just redirect me right back quick update in the edit I completely forgot to mention this in the actual video uh the really important thing right here is this authorization callback URL the way we're telling GitHub to send them back to off/ callback GitHub is by putting that in right here that's not anywhere in the codebase that's right here and I forgot to mention that You' really need to configure this so that's why they whenever we sign in there they get redirected to this call back and then we can go ahead and fulfill it which you're about to see they got sent to o/c callback GitHub to this page right here and this is where we actually validate that they had a valid ooth session what we're really doing with this ooth is we go to GitHub servers we log in on their thing and then they'll send back a code saying hey this is valid you can log them in we grab this code out of the search programs we grab the state out of the search programs do a bunch of validation make sure all this stuff is here make sure our storage state is in here then finally we can go ahead and actually sign in our user now we're using ooth here so whenever they sign in it's kind of an upsert operation because we're going to want to if they don't already have a user account saved within our database we need to save that but if they do already have a user account then we want to just log them in so what we're going to go ahead and do is we're going to grab our tokens here we're going to fetch some information about the users using the GitHub API because we now have an access token we're going to go ahead grab our GitHub user I've put down some useful types here there's a lot more uh it's not fully typed but I just grabbed these cuz these are the ones I care about uh we also these are the types on the email response that we can get so we're going to go down here we're going to get all of this information from GitHub land we're going to go ahead then and check and see if we already have a user at our database so we're going to find the first one that matches remember what I said earlier that we're using these compound primary keys or composite primary keys this is why we're going to be looking for the user where their provider is GitHub and their provider id is the GitHub user. ID so we grab this existing user if they exist then we just need to create their session set their session cookie and send them back so we go ahead head do all that right in here Lucia has the built-in methods for doing this this is the kind of nice stuff it does for you instead of having to go through and manually create the cookie and then set it and do all this crap we can just go ahead create our session create our session cookie set our cookie right here and then that's it that's all we have to do now in the other case when the user doesn't already have an account we need to go ahead and create their account so the first thing we're going to do is we're going to go ahead and grab their email we want to grab the email from their account then um this is kind of a mess I kind of just wrote this and it works and I haven't really had time to go through and fix it but effectively all we're really doing here is we're going to get back a list of all the emails attached to their GitHub account we want to grab their primary email and then we want to go ahead in here and create the user so the name parts is going to be they'll send back like my name is Benjamin Davis so it'll send back that as a string so I want to split that to get the two parts of the name I want to grab their user ID which we're going to generate here like I said this is just to make it easier to set up our relations and stuff within the database then we want to go ahead and create the user so we're going to insert our user into the database then the exact same thing as before create our session create our cookie and set our cookie and then at the end of that and then at the end of it we're done we just go ahead and we redirect the user back to the homepage and that's where I am right here and that's all we need to do to get the user signed in and create the account if you look at the Google implementation here it's basically the exact same thing but a little bit different um you can take a look at the code link down below again this is also in the Lucia documentation um every ooth provider is going to do this slightly differently there's going to be slightly different things you need to do up here at the top to get all the users information but generally speaking it's the same flow of you validate their code and then once you've done that you need to create the user or just sign in the user okay so now that we're signed in and we've got everything working it is super trivial to actually work with this in our app when you're setting up Lucia what you want to do is you want to add them to your locals so we're going to extend our locals interface here we're going to type user and session here import them from Lucia set the type and then we're going to go within our hooks. server. TS we're going to go ahead and say we're going to grab our session and user out of our lucia. validate session uh ensure that our cookies are all valid and we've got everything done here and then we're going to go ahead and say event. locals. user equals user and event. locals. session equals session so that means anytime if I go in any of my like page. servers or whatever if I add it in here I add it in a parameter right here we'll do locals we'll do const user equals locals. user I now have full access to the user object right here so this is going to be user or null it's going to have all those information all the information I need and that's super super helpful um if you can see a great example of this actually being used in um whoops we'll do this you can see a great example of this actually being used with our little Ure admin method if we look at our off. TS file here down here I have this nice little helper method called ensure admin all this is going to do is it's going to take in our locals object it's going to check and make sure that the user and the session are there and then it's going to check and make sure that the user is logged in and that they're an admin so on all of my admin routes here so we go to like um server. TS on my products route here if I want to delete a product it will first ensure that the users an admin and if they're not an admin it'll just redirect them out of this so we can just use this right here to protect any of our Roots as we need and it is super super helpful and super super easy signing out is just as trivial all we have to do is just go to sign or I think I did it as log log out yep logging out is super simple I just created this new get request endpoint where we just grab their session if they have a session we want to go ahead invalidate that session which will'll delete it out of our database we want to set the session cookie to be blank we set that to be the actual cookie then we redirect them to the login page we can fire this by going over here to the profile page pressing log out and that's it our user is now logged out like I said this entire codebase is open source and it's link down below you are free to use anything you want in here uh just not The Branding and assets let me know if you guys have any questions like I said authentication is really not nearly as hard as it used to be and I will talk to you soon
Info
Channel: Ben Davis
Views: 2,534
Rating: undefined out of 5
Keywords:
Id: xahLLwrxW2Y
Channel Id: undefined
Length: 14min 9sec (849 seconds)
Published: Tue Feb 27 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.