Authentication Logic with Session IDs and User Creation
00:00 Let's open up the AuthServerUtils, and we're going to keep this user ID key variable name because other files are using it. We'll fix that in the next step of the exercise. But we are going to change the actual value to session ID to communicate what it actually is. We're going to then rename this to session ID
00:18 because that's now actually a session ID. Then instead of querying the user table, we're now storing session IDs, and so we're going to look for this in the session table that we just made. So this is going to give us back a session. Then let's see, if we don't find the session,
00:38 we're going to log the user out, same thing there. Then here we need to return the user ID from the session, because remember, this is get user ID, not get session ID. So we're going to add a select here to get the user ID out of this query here, and then we can say session.userID. There we go. In fact, we probably don't need to
00:58 select the ID of the session either. We just need to resolve the session ID to a user ID, and that takes care of that. All right. So then our require user ID, that is going to just be built on top of the get user ID, same as require anonymous and require user, all of these just built on top of
01:17 that other utility so we don't need to change those. For login, this is going to be a little different. So right now, verify user password can return a user that has an ID or it can return null. So we're going to do an early return of null. So if there's not a user, then return null.
01:33 So far, we haven't actually changed anything functional yet. But instead of just leaving it at that, we actually need to create a session for the user to be logged in. So let's get our session is await Prisma session create,
01:48 and we're going to want to select the ID and the expiration date, and instead of expires out, we called it expiration date. So we're going to need to select those things from the thing that we're about to create, and our data for this creation is going to involve the user ID.
02:07 So this is the user that we're signing or logging in, and then the expiration date, we'll just call get session expiration date. There you go. That gets us our session, and we can then return the session instead of the user, because what we're getting from login is
02:24 a session which will have an ID which we put into our cookie. Okay. Sign up is going to be a little bit more complicated than the login. So instead of creating a user as part of the user query, we're actually going to be creating a session and returning the session, but we still need to create the user because they're signing up for the first time.
02:44 So what we'll do is I'm going to take this right here, and we'll make this a sub create of a session creation. So here then we say user and create, and then all this stuff goes in there. So we've got a double sub create right there. Now we're talking.
03:03 Okay. So we're going to need a expiration date set here, and that's get session expiration date. Then all that we need here is the ID and also the expiration date as well. With that, we can return the session which we're doing, we're just calling it user. So let's call it session.
03:22 There we go. Now our sign up and our login are correct. You may have noticed we refreshed and now we're in a funny state because I've got a session key or a cookie that has the user ID, but we're looking at the session ID. So now that cookie has actually been
03:41 deleted because the logic that we stuck in there earlier, which is interesting how that all worked out. All right. The last step here is we want to get the session ID from the cookie session. So session ID. The reason that we need to do this is because there's a session in
04:00 the database that should probably be deleted if we're going to log the user out. So we're going to say prisma.session.delete, where the session ID matches what the user had before. Now, it's possible that this function,
04:17 this logout function could be called when the user is not actually logged in at all. So then the session ID would be null or it could be something else entirely. Frankly, I'm not very interested in preventing the user from being logged out in the event
04:36 that there's some error deleting the session. Because having that session itself in the database doesn't actually break anything or cause any problems. So what we're going to do is add a catch here to just silently accept any errors and that's fine. If you want to, you can add a console error there or something.
04:54 But yeah, so if there's no session ID in there, maybe it got deleted or something, that's fine. It's not going to hurt anybody if that deletion fails. As a part of that, I don't want to wait for this delete to finish before we let the user log themselves out.
05:11 So I'm going to add a void instead of a wait right here. What this does is it just says, ignore the return value of this thing. We could just leave it like this, but I like to communicate, no, I thought about this. I don't want to add an await here, I want to add a void, which means we're going to just ignore that and it will
05:29 proceed to the rest of the code even while this is still executing. Great. So that takes care of our logout. That's the whole thing, what we've done so far. So let's just review really quickly, and then we can move on to the next step to actually finish the whole process here.
05:47 So our user ID key is what we've reassigned to session ID. We've updated some variable names here. We're selecting the user ID and returning that. Our utils are not affected here. Login had to also create a session and return that session. We want to make sure we return
06:07 the expiration date because we're going to use that in a little while, and we generate that with the get expiration date utility that we have. Then we also create a session when we sign up, and we nest the user create as part of that session creation. Then in our logout, we make sure to delete the session from the database,
06:26 so we don't have extra stuff lying around. We don't want to wait for that, so we just add a void, and we don't want to worry about errors in the event that there's some problem deleting it, so we just add a catch. That is the first part of what we're doing here.