1 00:00:00,540 --> 00:00:02,430 Instructor: We've now got some fantastic logic 2 00:00:02,430 --> 00:00:05,190 for creating a new user account. 3 00:00:05,190 --> 00:00:08,280 We read in the email and password of request, 4 00:00:08,280 --> 00:00:10,260 we see if there's already a duplicate. 5 00:00:10,260 --> 00:00:13,260 If there's not, we go ahead and create a user and save it. 6 00:00:13,260 --> 00:00:15,810 So this is all looking pretty great right now. 7 00:00:15,810 --> 00:00:17,760 One thing that you may have noticed if you've played around 8 00:00:17,760 --> 00:00:20,070 with the current logic at all in Postman 9 00:00:20,070 --> 00:00:23,883 is that while we can successfully create an email, 10 00:00:24,810 --> 00:00:27,210 create a user with an email and a password, 11 00:00:27,210 --> 00:00:29,970 I just submitted these and I got success is true. 12 00:00:29,970 --> 00:00:33,390 If I delete the email, I don't send any email along, 13 00:00:33,390 --> 00:00:34,950 let's see what happens. 14 00:00:34,950 --> 00:00:37,920 I'm gonna send and I still get success true back 15 00:00:37,920 --> 00:00:40,410 even though I didn't provide an email address. 16 00:00:40,410 --> 00:00:42,300 Let's open up Robomongo and see 17 00:00:42,300 --> 00:00:44,350 what this looks like inside the database. 18 00:00:45,450 --> 00:00:47,490 So I'm gonna open Robomongo. 19 00:00:47,490 --> 00:00:49,170 I'm gonna open my connections tab 20 00:00:49,170 --> 00:00:51,093 and I'm gonna connect to localhost. 21 00:00:52,260 --> 00:00:55,590 At this point, you should now see an auth database in here. 22 00:00:55,590 --> 00:00:58,830 If we expand that and then we expand collections, 23 00:00:58,830 --> 00:01:00,810 we can see this users collection 24 00:01:00,810 --> 00:01:04,110 and it's called "users", lowercase U specifically, 25 00:01:04,110 --> 00:01:05,790 specifically 'cause that's how we wired up 26 00:01:05,790 --> 00:01:09,090 to Mongoose inside of our user model file. 27 00:01:09,090 --> 00:01:11,970 Over here, you can see that I've got two records. 28 00:01:11,970 --> 00:01:14,250 One has the email that I just created 29 00:01:14,250 --> 00:01:16,830 and then the other one has a password and ID 30 00:01:16,830 --> 00:01:18,930 but not an email address. 31 00:01:18,930 --> 00:01:20,820 So it looks like our server is currently 32 00:01:20,820 --> 00:01:24,180 letting us save or create new users, 33 00:01:24,180 --> 00:01:27,480 even if an email and password were not passed in. 34 00:01:27,480 --> 00:01:30,513 So let's add a little check just to guard against that case. 35 00:01:31,560 --> 00:01:33,960 Inside of my authentication controller, 36 00:01:33,960 --> 00:01:37,582 I'm gonna say, "If there is not an email 37 00:01:37,582 --> 00:01:39,060 (keyboard keys clattering) 38 00:01:39,060 --> 00:01:41,411 or there is not a password, 39 00:01:41,411 --> 00:01:43,380 (keyboard keys clattering) 40 00:01:43,380 --> 00:01:47,730 return early with a status of 422, 41 00:01:47,730 --> 00:01:49,833 and send back a message of, 42 00:01:51,712 --> 00:01:55,317 'You must provide email and password', 43 00:01:57,270 --> 00:01:58,103 like so." 44 00:02:00,180 --> 00:02:02,730 Now, if I go back over to Robomongo 45 00:02:02,730 --> 00:02:05,040 and I delete both of the records that I just made, 46 00:02:05,040 --> 00:02:07,230 so I'm just gonna forcibly delete them 47 00:02:07,230 --> 00:02:09,930 by right clicking and then clicking "Delete document." 48 00:02:14,520 --> 00:02:16,680 Now I'll go back over to Postman. 49 00:02:16,680 --> 00:02:19,110 I'm going to make my request again without a password, 50 00:02:19,110 --> 00:02:21,570 excuse me, again without an email. 51 00:02:21,570 --> 00:02:24,150 I'll send, and now I correctly get an error message 52 00:02:24,150 --> 00:02:27,150 that says, "You must provide an email and a password." 53 00:02:27,150 --> 00:02:30,210 And if I go look at Robomongo, 54 00:02:30,210 --> 00:02:32,160 I did not create any users. 55 00:02:32,160 --> 00:02:34,957 So I successfully exited out early and said, 56 00:02:34,957 --> 00:02:37,140 "Nope, don't need to make a record in this case 57 00:02:37,140 --> 00:02:40,740 because the email and password are not valid." 58 00:02:40,740 --> 00:02:42,600 I could also put in a little bit of authentication 59 00:02:42,600 --> 00:02:44,520 or a little bit more validation here, 60 00:02:44,520 --> 00:02:47,010 just to verify that the email that was passed in 61 00:02:47,010 --> 00:02:48,600 is actually looks like an email. 62 00:02:48,600 --> 00:02:49,860 You know, it has an "@" symbol, 63 00:02:49,860 --> 00:02:51,873 a domain on it, et cetera, et cetera. 64 00:02:54,480 --> 00:02:55,800 So this is looking pretty good. 65 00:02:55,800 --> 00:02:56,640 I like how we are. 66 00:02:56,640 --> 00:02:57,473 I like where we're at. 67 00:02:57,473 --> 00:02:59,580 We're handling a couple edge cases here. 68 00:02:59,580 --> 00:03:01,380 Just one small thing. 69 00:03:01,380 --> 00:03:04,620 If I create a new user in Postman, 70 00:03:04,620 --> 00:03:06,450 so I'm gonna go back over to Postman, 71 00:03:06,450 --> 00:03:09,064 I'm going to add on email here, 72 00:03:09,064 --> 00:03:12,647 (keyboard keys clattering) 73 00:03:14,340 --> 00:03:16,143 and then, I'll send it across. 74 00:03:17,100 --> 00:03:18,900 The account was successfully made. 75 00:03:18,900 --> 00:03:21,420 I'm gonna go back over to Robomongo. 76 00:03:21,420 --> 00:03:23,613 I'm gonna refresh by hitting command R. 77 00:03:24,660 --> 00:03:25,590 Now I can see that 78 00:03:25,590 --> 00:03:27,750 I successfully have an email and a password. 79 00:03:27,750 --> 00:03:29,640 Just one small thing here. 80 00:03:29,640 --> 00:03:33,420 The password is send in my database as plain text. 81 00:03:33,420 --> 00:03:37,230 So in the security world, this is a big, tremendous no-no, 82 00:03:37,230 --> 00:03:40,950 we never wanna save a plain text password. 83 00:03:40,950 --> 00:03:44,730 If some malicious actor ever got access to our database, 84 00:03:44,730 --> 00:03:47,220 they could grab all of our users' credentials, 85 00:03:47,220 --> 00:03:50,490 not only the emails, but also the unencrypted passwords. 86 00:03:50,490 --> 00:03:53,130 And this is basically a worst case scenario. 87 00:03:53,130 --> 00:03:55,230 If your users' passwords and plain text 88 00:03:55,230 --> 00:03:56,640 get out there in the open, 89 00:03:56,640 --> 00:03:58,080 you're gonna have a very hard time 90 00:03:58,080 --> 00:03:59,883 explaining that to your customers. 91 00:04:00,780 --> 00:04:02,220 So whenever we store a password, 92 00:04:02,220 --> 00:04:05,310 we always want to store a encrypted password, 93 00:04:05,310 --> 00:04:07,350 an encrypted version. 94 00:04:07,350 --> 00:04:08,850 So we need to go back to our, 95 00:04:08,850 --> 00:04:11,670 into our logic and update the logic 96 00:04:11,670 --> 00:04:13,140 that's gonna save the password here. 97 00:04:13,140 --> 00:04:16,923 And we wanna replace this with an encrypted password. 98 00:04:19,110 --> 00:04:22,740 To handle this, we're going to use a library called Bcrypt. 99 00:04:22,740 --> 00:04:25,890 Bcrypt is a extremely popular library 100 00:04:25,890 --> 00:04:29,400 for encrypting passwords before they get saved. 101 00:04:29,400 --> 00:04:31,650 Bcrypt is a separate package in Node, 102 00:04:31,650 --> 00:04:34,710 so it's something that we have to install ourselves. 103 00:04:34,710 --> 00:04:37,620 As with all other packages that we've had ever installed, 104 00:04:37,620 --> 00:04:40,770 we are going to install it from the NPM tool. 105 00:04:40,770 --> 00:04:42,090 So back over my terminal, 106 00:04:42,090 --> 00:04:44,133 I'm going to end my server process. 107 00:04:45,900 --> 00:04:48,190 And then I'll run "npm install 108 00:04:49,398 --> 00:04:53,820 -: -save Bcrypt-nodejs". 109 00:04:53,820 --> 00:04:56,250 This is gonna grab the node version of Bcrypt 110 00:04:56,250 --> 00:04:57,153 and install it. 111 00:04:59,071 --> 00:05:01,710 (clearing throat) 112 00:05:01,710 --> 00:05:03,840 So Bcrypt is very compact, very small, 113 00:05:03,840 --> 00:05:06,330 and so it installs almost immediately. 114 00:05:06,330 --> 00:05:07,953 And then we'll go ahead and, 115 00:05:09,120 --> 00:05:11,907 start our server back up with "npm run dev". 116 00:05:14,280 --> 00:05:15,810 Okay. 117 00:05:15,810 --> 00:05:18,810 So one thing about Bcrypt, you know, it's fantastic library, 118 00:05:18,810 --> 00:05:20,280 it really gives us a lot of security. 119 00:05:20,280 --> 00:05:22,680 The only kind of weird thing about it is that 120 00:05:22,680 --> 00:05:26,670 it is not the easiest thing to understand from the Gitgo. 121 00:05:26,670 --> 00:05:27,570 So here's what we're gonna do. 122 00:05:27,570 --> 00:05:29,220 We're going to wire up Bcrypt, 123 00:05:29,220 --> 00:05:30,840 we're gonna implement it inside our app, 124 00:05:30,840 --> 00:05:32,010 we're gonna see it work, 125 00:05:32,010 --> 00:05:34,170 and then we're gonna talk about exactly what's going on 126 00:05:34,170 --> 00:05:35,190 with Bcrypt, okay? 127 00:05:35,190 --> 00:05:37,140 So we're gonna do a lot of typing to start off with. 128 00:05:37,140 --> 00:05:38,760 We're gonna put on the code. 129 00:05:38,760 --> 00:05:41,220 It's gonna look pretty weird, but after we do that, 130 00:05:41,220 --> 00:05:43,830 we'll talk about exactly what's going on. 131 00:05:43,830 --> 00:05:45,480 So here's the code we're gonna write. 132 00:05:45,480 --> 00:05:47,490 We're gonna flip over to our user model, 133 00:05:47,490 --> 00:05:49,263 so our user.js file. 134 00:05:50,400 --> 00:05:53,850 At the top, we're going to import the Bcrypt library. 135 00:05:53,850 --> 00:05:56,177 So const 136 00:05:56,177 --> 00:05:57,760 Bcrypt require 137 00:05:58,920 --> 00:06:00,723 Bcrypt nodejs. 138 00:06:01,740 --> 00:06:02,940 And then, here's where things are gonna get 139 00:06:02,940 --> 00:06:03,773 a little interesting. 140 00:06:03,773 --> 00:06:05,880 So just again, bear with me for a little bit. 141 00:06:05,880 --> 00:06:08,167 I'm gonna add another section in here that says, 142 00:06:08,167 --> 00:06:10,447 "On Save Hook, 143 00:06:10,447 --> 00:06:12,030 (keyboard keys clattering) 144 00:06:12,030 --> 00:06:13,437 encrypt password". 145 00:06:15,090 --> 00:06:16,290 So now we're gonna do the typing. 146 00:06:16,290 --> 00:06:18,090 This is gonna be the, kind of crazy part. 147 00:06:18,090 --> 00:06:20,190 Again, just bear with me for a bit. 148 00:06:20,190 --> 00:06:22,680 We're going to take our userSchema object, 149 00:06:22,680 --> 00:06:24,690 which we defined above. 150 00:06:24,690 --> 00:06:26,970 We're going to call "pre" on it, 151 00:06:26,970 --> 00:06:28,170 P R E. 152 00:06:28,170 --> 00:06:29,980 We're gonna pass a string of save 153 00:06:30,870 --> 00:06:33,510 and then a function with an argument. 154 00:06:33,510 --> 00:06:34,860 Next, 155 00:06:34,860 --> 00:06:37,050 again, we're gonna talk about all this stuff. 156 00:06:37,050 --> 00:06:39,120 Just let's get the code on the screen first 157 00:06:39,120 --> 00:06:40,530 because it's a lot easier to explain 158 00:06:40,530 --> 00:06:41,780 after it's on the screen. 159 00:06:42,780 --> 00:06:46,320 I'm gonna put const user equals this, 160 00:06:46,320 --> 00:06:48,100 then, Bcrypt 161 00:06:48,960 --> 00:06:50,910 genSalt 162 00:06:50,910 --> 00:06:52,710 number 10. 163 00:06:52,710 --> 00:06:55,200 We're gonna put in another function 164 00:06:55,200 --> 00:06:57,837 whose arguments are "err" and "salt". 165 00:07:00,300 --> 00:07:02,110 We'll say, "if err 166 00:07:03,240 --> 00:07:05,070 return next err." 167 00:07:05,070 --> 00:07:07,860 So again, this is a little bit of error handling. 168 00:07:07,860 --> 00:07:09,990 Then just one more big step in here. 169 00:07:09,990 --> 00:07:13,350 We're gonna say, "Bcrypt hash 170 00:07:13,350 --> 00:07:15,900 user.password, 171 00:07:15,900 --> 00:07:17,220 salt, 172 00:07:17,220 --> 00:07:18,450 null", 173 00:07:18,450 --> 00:07:19,570 another function 174 00:07:21,690 --> 00:07:24,207 with arguments, "err" and "hash". 175 00:07:25,950 --> 00:07:28,680 Finally, if err 176 00:07:28,680 --> 00:07:30,963 return next err, 177 00:07:33,090 --> 00:07:34,113 otherwise, 178 00:07:35,465 --> 00:07:38,460 user.password equals hash, 179 00:07:38,460 --> 00:07:40,200 and next. 180 00:07:40,200 --> 00:07:41,670 All right, so a lot of typing. 181 00:07:41,670 --> 00:07:44,070 I would love if you pause the video at this point 182 00:07:44,070 --> 00:07:46,080 and just took a look at all the code on here. 183 00:07:46,080 --> 00:07:48,270 Make sure that you transcribed everything correctly 184 00:07:48,270 --> 00:07:50,190 'cause we just did a whole bunch of typing 185 00:07:50,190 --> 00:07:52,860 without really being clear about what was going on. 186 00:07:52,860 --> 00:07:54,900 I also encourage you to open up your terminal 187 00:07:54,900 --> 00:07:57,030 and just verify that you're not getting any typos 188 00:07:57,030 --> 00:07:57,900 or any errors in here. 189 00:07:57,900 --> 00:08:00,420 If you're getting any typos or any errors at this point, 190 00:08:00,420 --> 00:08:02,580 you might have a typo in the code that you just wrote. 191 00:08:02,580 --> 00:08:05,430 So, do make sure that everything is showing up correctly. 192 00:08:06,450 --> 00:08:08,130 All right, so we've got the code on the screen. 193 00:08:08,130 --> 00:08:09,540 Let's go through an explanation 194 00:08:09,540 --> 00:08:10,860 of exactly what's going on, 195 00:08:10,860 --> 00:08:11,943 in the next section.