1 00:00:00,720 --> 00:00:05,480 In this video we're going to start to implement password hashing during the sign up process. 2 00:00:05,500 --> 00:00:09,900 Now there are many different ways of implementing this and if you take a look online at some different 3 00:00:09,900 --> 00:00:15,300 tutorials on how to implement password hashing while using Mongo DB and Mongoose you're going to see 4 00:00:15,300 --> 00:00:20,520 that a lot of them recommend that you place all this password hashing logic directly into your user 5 00:00:20,520 --> 00:00:21,730 model file. 6 00:00:21,730 --> 00:00:27,000 So in other words inside of our models user yes we would write out a lot of code to hash the password 7 00:00:27,210 --> 00:00:29,240 and then store it along with the user. 8 00:00:29,250 --> 00:00:34,200 Now we are going to do something similar to that but we're going to break our logic up here into two 9 00:00:34,200 --> 00:00:35,490 separate files. 10 00:00:35,520 --> 00:00:41,640 We're going to make a separate file or more specifically a separate class that is just responsible for 11 00:00:41,640 --> 00:00:44,500 taking a string and hashing it. 12 00:00:44,550 --> 00:00:49,680 We're also going to have inside that class a function that's going to compare two different hash strings 13 00:00:49,710 --> 00:00:50,770 as well. 14 00:00:50,880 --> 00:00:55,320 So the majority of the actual hashing logic that actual implementation is going to be in the separate 15 00:00:55,320 --> 00:01:00,600 file in a separate class and we're going to use that inside of our user model file. 16 00:01:00,600 --> 00:01:06,060 The reason we're doing this is to just keep our user model file a little bit cleaner because right now 17 00:01:06,070 --> 00:01:09,680 there's a lot of stuff already inside of here and a lot of the stuff is pretty confusing. 18 00:01:09,750 --> 00:01:12,780 So I want to limit the complexity of this file as much as possible. 19 00:01:12,780 --> 00:01:16,830 That's why we are going to place a lot of this hashing stuff in another location. 20 00:01:17,160 --> 00:01:17,940 So let's get to it. 21 00:01:17,940 --> 00:01:21,910 Let me show you how we're gonna build up this password hashing stuff in a separate location. 22 00:01:23,740 --> 00:01:25,080 Somebody as our city directory. 23 00:01:25,110 --> 00:01:28,240 I'm gonna make a new folder called services. 24 00:01:28,260 --> 00:01:30,000 There's probably a better name for this folder. 25 00:01:30,000 --> 00:01:34,440 I like to create a Services Directory for just a lot of kind of general purpose things that are floating 26 00:01:34,440 --> 00:01:35,990 around my application. 27 00:01:36,140 --> 00:01:39,360 Again probably could think of a better name but this will work for right now. 28 00:01:39,690 --> 00:01:42,940 Inside there I'm gonna make a new file called Password dot. 29 00:01:42,970 --> 00:01:53,780 Yes and then inside of that I'll export a new class called password and I'm going to give this class 30 00:01:53,780 --> 00:01:56,810 password to different static methods. 31 00:01:56,810 --> 00:02:04,470 I'm going to say static to hash we're going to receive a password as a string. 32 00:02:04,580 --> 00:02:09,890 I'll make a sec separate method that's also static to compare. 33 00:02:09,980 --> 00:02:18,840 This is going to take a stored password that is a string and a supply password that is a string 34 00:02:22,010 --> 00:02:24,650 quick reminder on what a static method is. 35 00:02:24,690 --> 00:02:29,310 Static methods are methods so we can access without creating an instance of the class. 36 00:02:29,350 --> 00:02:35,700 So for example we can call both these methods right here by simply calling password dot to hash or password 37 00:02:35,750 --> 00:02:36,090 Dot. 38 00:02:36,100 --> 00:02:42,020 Compare this is opposed to what normal methods or instance methods such as if we had a method on here 39 00:02:42,020 --> 00:02:44,050 like print to access print. 40 00:02:44,240 --> 00:02:50,960 We would have to first make a new instance of password and then on there we could access print 41 00:02:58,140 --> 00:03:02,010 so we're going to implement our hashing logic here and then some logic right here to actually compare 42 00:03:02,040 --> 00:03:07,410 a stored password and a supplied one so for handling the two hash parts. 43 00:03:07,420 --> 00:03:12,370 This is where we want to take in a plain text password and somehow hash it out a logic that we're gonna 44 00:03:12,370 --> 00:03:14,380 write out inside of here is gonna be a little bit specialized. 45 00:03:14,410 --> 00:03:19,570 Again I'm going to kind of assume that you have seen password hashing at least once in the past if you 46 00:03:19,570 --> 00:03:20,140 haven't. 47 00:03:20,140 --> 00:03:25,090 Again I recommend doing a little quick log search online look at a tutorial or two. 48 00:03:25,120 --> 00:03:29,710 There's a ton of resources out there so for the most part we're just going to throw in a bunch of code 49 00:03:29,740 --> 00:03:30,870 rather quickly. 50 00:03:31,180 --> 00:03:42,220 At the very top I'm going to imports s script and random bytes from the built in node library of crypto. 51 00:03:42,240 --> 00:03:49,730 I'm also going to get the promise of fi function from you till s script is the hashing function that 52 00:03:49,730 --> 00:03:51,290 we're going to use. 53 00:03:51,300 --> 00:03:52,730 Script is fantastic. 54 00:03:52,730 --> 00:03:55,800 The downside to it is that it is callback based. 55 00:03:55,850 --> 00:03:58,030 We want to eventually use async await. 56 00:03:58,100 --> 00:03:59,860 We're doing a lot of logic inside of here. 57 00:04:00,020 --> 00:04:05,330 So I got problems of fi so we can take this callback based function and turn it into a promise based 58 00:04:05,330 --> 00:04:08,920 implementation which is compatible with using async await. 59 00:04:08,960 --> 00:04:18,310 So I'm going to say const script async is promise of Fi s script like so. 60 00:04:18,360 --> 00:04:25,470 So again just going from the callback implementation to a promise based implementation so then inside 61 00:04:25,470 --> 00:04:29,790 of here we're going to generate a salt which is a part of the hashing process. 62 00:04:30,030 --> 00:04:38,300 So I'll say con salt is random bytes eight to string X that's going to generate a random string for 63 00:04:38,300 --> 00:04:38,600 us 64 00:04:41,500 --> 00:04:47,390 and then going to do the actual password hashing process when we use s script async or really script 65 00:04:47,410 --> 00:04:48,040 in general. 66 00:04:48,040 --> 00:04:52,720 We get back what is called a buffer which is kind of like an array with raw data inside of it. 67 00:04:53,080 --> 00:04:59,410 So we are going to create a variable right here called buff short for buffer I'm going to do it in a 68 00:04:59,610 --> 00:05:07,950 s script async I'm going to pass in the password and the salt and a number of sixty four right here 69 00:05:09,390 --> 00:05:12,020 we immediately get an error because we're using a wait. 70 00:05:12,030 --> 00:05:16,910 So if you want to use the await syntax we need to mark the enclosing function as async as usual. 71 00:05:17,150 --> 00:05:22,460 I'll do so right away now if we mouse over buffer right here. 72 00:05:22,590 --> 00:05:26,400 You'll notice that unfortunately typescript is getting a little bit confused because it doesn't really 73 00:05:26,400 --> 00:05:29,040 know what happened during this promise five process. 74 00:05:29,380 --> 00:05:35,190 So we mouse over buffer its type is annotated as unknown typescript is saying I have no idea what is 75 00:05:35,190 --> 00:05:36,320 going on here. 76 00:05:36,540 --> 00:05:40,410 So we're going to fix this up by just telling typescript exactly what buffer is. 77 00:05:41,130 --> 00:05:44,580 I'm going to wrap this entire a weight statement with a set of parentheses. 78 00:05:44,580 --> 00:05:50,860 And then at the very end I'll put on as buffer that's telling typescript look we know what's going on 79 00:05:50,860 --> 00:05:51,180 here. 80 00:05:51,190 --> 00:05:53,460 This is a buffer just treat it as such. 81 00:05:53,500 --> 00:05:55,330 If I now mouse over above. 82 00:05:55,660 --> 00:06:02,400 Now this thing is recognized as being a buffer now finally we're going to return the hashed results 83 00:06:02,550 --> 00:06:04,030 along with these salts. 84 00:06:04,160 --> 00:06:08,830 I'm going to return a template string so note the back ticks here. 85 00:06:08,830 --> 00:06:15,780 Not single quotes I'm going to put in here above dot to string ex because remember we are working with 86 00:06:15,780 --> 00:06:17,740 a buffer which is not the same as a string. 87 00:06:17,740 --> 00:06:25,710 So we have to turn it into a string then at the very end I'm going to put a dot and then put on the 88 00:06:25,710 --> 00:06:27,570 rest which is our salt 89 00:06:30,980 --> 00:06:31,230 OK. 90 00:06:31,260 --> 00:06:36,750 So that is our two hash function it's going to take in some password or essentially any arbitrary string 91 00:06:37,230 --> 00:06:43,970 generate assaults it's going to hash the password along with the salt and then we're going to return 92 00:06:44,000 --> 00:06:50,960 both the hash password and the salt concatenated together and joined by a little dot. 93 00:06:51,110 --> 00:06:52,250 That's pretty good. 94 00:06:52,250 --> 00:06:55,580 Well let's take a quick pause right here and then we're going to implement the compare function in the 95 00:06:55,580 --> 00:06:56,540 next video as well.