A second and third version of this course released using Next 13+, but this course is great if you want to see another example fullstack project. We now recommend you take the Build an AI-Powered Fullstack Next.js App, v3 course.

Check out a free preview of the full Build a Fullstack App with Next.js, v2 course:
The "Password Management" Lesson is part of the full, Build a Fullstack App with Next.js, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Scott uses the bcrypt npm package to create two password authentication utility functions. The hashPassword function receives a plain-text password and returns a hashed version. The comparePasswords function receives a plain-text password and a hashed password. It determines if the plain-text version matches the hash.

Get Unlimited Access Now

Transcript from the "Password Management" Lesson

>> So we left off last with the auth form where we created the auth form and added it to the pages, the sign in page and the register page. Now we need to actually make the API routes and all the utility functions necessary to make the auth form work.

[00:00:22] So we can get in our app, so let's take a look at that. So like always gonna head over to the notes here you go, take a look at. So we did the pages now if you go look at this next one, we're going to focus on passwords because when we wrote the seed script we just went ahead and just put plain text passwords in there which you know for obvious reasons we don't want plain text passwords in the database so we need to be able to hash those passwords and check those passwords for sign in and things like that.

[00:00:53] So that's what we need to do. So we're going to make some utility functions that we're going to use inside of our API handlers that are all form is going to make API calls to so we can sign in and register. So let's do that. So first things first is, to get to this code, And if you remember how I organize my code, I like to just put separate things out.

[00:01:22] So in my lib folder, we have this API we have this DB, I'm gonna get another one for auth. Like that. And then inside of here, we're gonna use bcrypt from a package called bcrypt. And this other package called Jose for something called, for JSON web tokens, which we'll get to later.

[00:01:46] But mostly we're just gonna use bcrypt here to hash passwords and compare those passwords. So let's do that. So we're just gonna import bcrypt and it should already be installed. If not, go ahead and install it. And I'm going to add a function here, hash password, like so.

[00:02:12] And it's just going to be bcrypt.hash. Hash It's gonna take in a plaintext password is its only argument or a hash. That's my thoughts. And I believe, yeah, this takes like how many rounds of salting you want to do there? And that's it. It's pretty simple. This is also async by default so when we use hash password we'll have to await it because it's got to happen asynchronously and not synchronously.

[00:02:45] This thing is frequent I guess. Maybe I don't have bcrypt. I'll just install it just in case let's see or maybe just wants the types, yeah it just wants the types for i. I thought they fixed this with an automatic that happens forever [INAUDIBLE] Maybe not, all right.

[00:03:08] Of course. So we got hash password, that's what we gonna use for sign up. But for sign in we gonna compare the passwords. We are going to take the plain text password that you post on the form and we are going to compare with the hash password for the users.safe.

[00:03:22] If they both match when both hash then you typed in the right password. If they don't, then you didn't. So that's what we're going to do now. So compare passwords like that. And this one's just gonna take, like I said, a plain text password and then the hashed password that should be saved in a database and we're just gonna compare them.

[00:03:47] So we'll just say clean text password here and then hashed password here. And I'm just gonna return bcrypt dot compare like that. And we're just gonna take the end plain text and then the hashed like that and me export that. Any questions on those two functions? Nothing unique to.

[00:04:26] It's very common in Node too. This pattern with bcrypt yeah.
>> So with the async versus sync functions, is there a reason why we choose one or the other? Like, do we want to do something while it's awaiting or?
>> Yeah, that's a great question. The question was the difference between sync and async.

[00:04:46] Why would we choose one over the other? Typically, in Node.js, you probably want to use async for most of the things because synchronous things are blocking the thread. That's because by default, Node is single threaded, as in, It can only, it can't run like things in parallel across multiple threads, but it can do them in the background, because of just the nature of how JavaScript is as far as like, you know, the async queue and things like that.

[00:05:14] So when we think there is some type of somewhat difficult computational work like hashing. If you can make that async without blocking the thread that will enable you and your server, to take in more requests while that's actually happening whereas if this was synchronous and I don't know let's say this thing took forever, you were trying to compute, you know, some algorithms on a chessboard or something.

[00:05:40] And it took a long time. You couldn't get any more requests to come in and your server would stall. Granted, I know we're using serverless, and that's not the case here because each function each serverless invocation is its own instance and it doesn't block another one from happening.

[00:05:53] So we don't have to worry about that. But you should probably still do things async when you can and not synchronous. It is also noted that you can spawn up multiple threads in Node.js as well, but by default, that's not enabled. Cool. Any other questions? Okay, because this file, auth.js, or auth.ts, is going to be used on the server, there's a chance that it could be imported in a server component somehow, maybe not directly, maybe indirectly through a module dependency tree.

[00:06:35] Because of that, we have to tell Next.js that there's gonna be a dependency that needs to be enabled in that server environment. So Next.js allows us to use it. And the way we can do that is if we go down to our next config. You can see that there's a property here called server components external packages.

[00:07:00] That's exactly what it sounds like. It's external packages that we want to use in our server components. And like I said, this file might be used in a server component eventually. It will be used in the server component eventually. So we'll have to add that here. If you don't, whenever your server component tries to import that file, it's gonna behave as if you've never installed that module.

[00:07:29] The Next.js team is getting together a list of commonly used modules and adding them to this by default. For instance, I know when version 13 came out, Prisma was not added, so you had to add it here, but now I think it's added by default, so you don't have to add Prisma.

[00:07:49] So, that's probably why if you did some of the Prisma stuff, you didn't run into any errors because it's already added. But for safety, you can add it as well. So, that list will probably keep growing, I'm sure. So server components run on the server, but they also run in like a somewhat contained environment on the server that Next.js is in charge of.

[00:08:13] So it's like yes, you get full access to everything. But you just need to make sure that Next.js is okay with it. There's also still some bugs where server component environment thinks that thinks that serverless functions are client components. So if you tried to import some server component code inside of a handler API handler, it might think that handler is a client component.

[00:08:40] So there's some things still happening there. But, I don't think we're right into that problem today, yes.
>> So, here looks like you're including that line, in experimental but
>> Yes, did I? Yeah, I didn't move it up one, thanks, sorry.