
Lesson Description
The "Authenticating Users" Lesson is part of the full, Next.js Fundamentals, v4 course featured in this preview video. Here's what you'd learn in this lesson:
Scott demonstrates the process of querying the users table based on the session's user ID and returning the first match. Scott also mentions that server actions rely on the context of an active HTTP request and will break if used outside of that context.
Transcript from the "Authenticating Users" Lesson
[00:00:00]
>> Scott Moss: Let's try to get the session, if there is no session, we will, okay, can you just go there? Thank you, there's no session, we will turn null, so we can say session equals, wait, make this async get session like this, if not a session, this person is not logged in, there is no person here.
[00:00:26]
If there is a session, we can try to get the user by the database, no worries, if you don't have any experience with databases or anything like that, it's super easy, I'm using something called drizzle for the orm. It's pretty simple, so in this case we're just going to do a select query from the users table where the user's ID equals whatever the session's user ID is, so you don't have to know that part, but it's trying to mix it up for you.
[00:00:57]
Const user equals await db, select from import users, I guess I already have something called users, I'll call this results, there we go, and then where. There's a lot of ways you can do the where stuff in Drizzle, but I'm gonna use this helper method called eq, which stands for equals, so I can say equals, I want the users table id property.
[00:01:31]
If that equals whatever the session.user id property is, then that's the match that I want, this always returns an array, there's a match, never returns the single one. So in this case I just return the first thing in the array or if it's not there, null. We'll log this error if there's an error and then from there just return null, so that is us getting the user by email, so now if we do that, if we go back to Man, I don't want to hit save here, like what did I change?
[00:02:15]
I'm not gonna hit save there, I don't know what's going on with that, if we go back to this auth this get userwrite email should now work, let me just get rid of the argument that I was passing games. We don't actually need that, and let's see if we can actually sign in or sign up now, so let's try that.
[00:02:40]
Yeah, I fixed that already, or did I not, I guess not, let me see, users, why did it import it twice? That's weird, there we go, okay, all right, sign up, I'll just say admin@test.com password is admin, Admin Admin Admin, try to sign in says nah, [LAUGH] that's actually really funny, let's see why it said that.
[00:03:19]
So here if existing user, did I use that one already, I don't think I use that one, let's see, userApp.com admin admin admin admin, okay, our shit's broke, let's fix it, so getuserbyemail is returning a match. So let's see what that is, log that on the server, adminemo.com admin admin admin, and we get back this, I already have a session in here or something.
[00:04:20]
See User by email, Users by, you know what, I just had a brain fart, this is get user by email, not get the current user in the session, yeah, I don't know why I just did that? Well, that's good, we can just rename this function, getcurrentuser, that's get current user, I'm like, why is that doing that, okay, and then get user by email, let's just make that, sorry about that, get the user by email?
[00:05:00]
This one does take an email so can do this and then do a try catch user would be await db, you actually do db, I'll need the async here DB Users, that should work. DB Query users Find first and then where equals users id or I'm sorry, users email equals this email, so you can do that and then return user turn, no, there you go.
[00:06:08]
Little quick get user by email, which makes a lot more sense. And then now I can take this, go here, add my email, which in this case would be data email like that, and then this case right here, same thing, data email, okay, I'll try that again now, User1@app.com admin admin admin admin.
[00:06:59]
There we go, I am now signed into the dashboard, I know I just went really fast, so I'll push this up if you are looking to catch up, and I'll just leave this here for one second. But before I move on, I think a really good convention is to like put your stuff in folders that describe the environment in which they run in, so like for me I have an actions folder.
[00:07:29]
So I know that everything in here is going to be a server action, and I have this file called doll that tells me that these are not server actions, right, you could also name your functions that way too. So all your actions might have the name action in it, so you might have like sign in action sign up action, so you just know that this is an action, it has access to the request or something like that.
[00:07:54]
Or put it in an object where you have an actions object or something like that, just do it in a way, create your own conventions around it because it can get confusing, I get confused by it all the time, as you just saw, so, yeah, it takes a minute.
[00:08:12]
>> Speaker 2: Is it fair to say that server actions or functions are basically just node code that's exposed by Next JS over HTTP, whereas your data layer type stuff is just native node code?
>> Scott Moss: Yep, native node code that never leaves the server, whereas the server action is exposed over HTTP, yep, that's the simplest solution I've ever heard someone describe it as, so, yeah, pretty good, pretty much.
[00:08:50]
>> Speaker 3: Another organization question.
>> Scott Moss: Yeah.
>> Speaker 3: Your actions need to be in the app directory.
>> Scott Moss: No.
>> Speaker 3: Okay.
>> Scott Moss: The only thing,
>> Speaker 3: That's just the route stuff.
>> Scott Moss: Yes, just for routes.
>> Speaker 3: Yeah, I won't ask that anymore [LAUGH].
>> Scott Moss: [LAUGH] Yeah, that was good, that's a good question.
[00:09:03]
>> Speaker 3: Triple checking.
>> Scott Moss: Only routes and API stuff, pages and API stuff, nothing else has to be in the app directory. You can put all that shit down here and like, literally until like two or three weeks ago, I would have just put all this stuff down here, and I don't know, I just got bored, I guess.
[00:09:23]
I just started putting here, so that's where it is, there's no wrong or right answer.
>> Speaker 3: I know a lot of folders. For instance, if you wanted to like make a folder that says called server and then all the server stuff lived in it.
>> Scott Moss: Yeah, that's a great, great convention, all the server stuff is in here, put it all in there, yeah, that works totally fine, yeah, wait, hold on, I think Next JS actually has a server folder convention.
[00:09:48]
I've never made a custom server with Next js, so I don't know, gotcha, they actually might.
>> Speaker 3: You may not want to call it that exactly. [LAUGH]
>> Scott Moss: Then let me see.
>> Scott Moss: Is it called the server, although they have a server TS file, yeah, so you could be careful, probably?
[00:10:05]
>> Speaker 3: Fine with directory.
>> Scott Moss: Right, so that's a thing, I've never used that, I hope I never have to, [LAUGH] any questions?
>> Speaker 2: I guess one more, this might just be my lack of knowledge on the node side, but is it, so when you're doing like a get session, you're, yeah, maybe pulling it up would be good, so you're looking at cookies, right.
[00:10:38]
And so is it, when that function is called, it's always kind of assumed that it's being called within the context of an active like HT HTTP request. So.
>> Scott Moss: Yep.
>> Speaker 2: That's why you can be confident that when you're calling that function, it's always in the right user context and you're getting the right cookie associated with a specific user, you don't have to like pass a user ID into this.
[00:11:10]
>> Scott Moss: Right, it's literally reading the headers that came in from the request and if you tried to use this outside of the context, you would get an error? So it either worked because you use it in the right place or it errored because you didn't use it in the right place, it will literally break as soon as you try to do this, nope, that doesn't work here.
[00:11:32]
>> Speaker 2: And the only config you have to do, or not even config, but just structure. You just have to make sure you're calling it within one of those server components. And that's good.
>> Scott Moss: Yep, right, so far I showed you how to use this stuff in a server action, now I'm gonna show you how to use this stuff in a server component, yeah, react should have been like this from day one.
[00:11:53]
Honestly, it really should, and also I want you to know like everything I'm showing you now, I would say 80% of people that use next JS don't know it like this or know it this well or even understand it. So to me this is like fundamentals, but it's also pretty advanced, so you guys are ahead of the game in my opinion, I have engineers that I work with that I'm still trying to explain this to.
[00:12:19]
And I don't think that it's hard, I think it's just very different, it's very different because once I understand it, I actually prefer this over making API routes and TRPC, all this stuff. I was just like, if I could just make a function and export it, and it was just on me to know when I'm supposed to use that function, I'd rather do that than learn these different libraries and these configurations, and I don't wanna do that.
[00:12:45]
>> Speaker 4: Quick question.
>> Scott Moss: Yes.
>> Speaker 4: So is there a way to have an open API exposure of APIs generated by next JS if you need to expose those APIs in a standard way?
>> Scott Moss: Yeah, we're gonna get to that, we're gonna make a developer API for our product so you can see how to expose that, and yes, you can use open API for that.
[00:13:06]
>> Speaker 4: Thank you, that's awesome.
>> Speaker 2: And then one, one kind of more follow up question to that is like, there's nothing saying or built into like next that prevents me from calling the sign in function just like from Postman, right.
>> Scott Moss: You wouldn't know the route for it, so you wouldn't know how to, it doesn't have a route associated for it until it's executed, if that makes sense, you wouldn't know what route to type in a postman to call it.
[00:13:43]
>> Speaker 2: Okay, I thought in the network tab, when we made the call, it just said like, slash sign.
>> Scott Moss: So that was just like typical HTML5, if you make any action on a form, it just does a post request to the page that you're on, that's just how form actions work.
[00:13:59]
>> Speaker 2: Right. Because it's a form. It's a HTML5 form.
>> Scott Moss: Yeah.
>> Speaker 2: Okay,.
>> Scott Moss: So it just did that, but if you use a server action outside of a form, which you can and we will, then you're not going to know, then you're not gonna know, it's just like, I don't know what URL that is.
[00:14:12]
Next JS is gonna make one, so you wouldn't know what it is, yeah.
>> Speaker 3: That'S almost a layer of security in and of itself.
>> Scott Moss: Yeah, it is, yeah.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops