1 00:00:00,860 --> 00:00:05,870 We've now added in two additional pieces of code to our user dot J as file so the priest spoke right 2 00:00:05,870 --> 00:00:10,610 here is gonna make sure that we always salt and hash a password anytime that we attempt to create a 3 00:00:10,610 --> 00:00:13,650 new user and store them inside of our database. 4 00:00:13,660 --> 00:00:17,740 The second thing we put inside of here was a method attached to every user that it gets created. 5 00:00:17,830 --> 00:00:23,170 That's going to automatically compare a password provided by the user against a password stored inside 6 00:00:23,170 --> 00:00:26,160 of our database so we can easily call this function now. 7 00:00:26,170 --> 00:00:28,260 Anytime a user tries to log in. 8 00:00:28,390 --> 00:00:33,580 Speaking of which let's go back over to our auth roots file and add in some code to log our user in 9 00:00:34,660 --> 00:00:34,960 OK. 10 00:00:34,970 --> 00:00:39,860 So back inside of all throughout I'm going to add in a new post request handler underneath the existing 11 00:00:39,860 --> 00:00:40,210 one. 12 00:00:40,280 --> 00:00:47,420 So I'll say router dot post and anytime someone calls the sign in route we're going to run this function 13 00:00:50,260 --> 00:00:54,870 as usual this callback will be invoked with a request and response object. 14 00:00:55,080 --> 00:00:59,500 So inside of here whenever a user tries to sign in we're going to expect that they provide us with an 15 00:00:59,560 --> 00:01:01,170 email and password. 16 00:01:01,420 --> 00:01:05,470 Those email and password properties will be on the record body property. 17 00:01:05,470 --> 00:01:13,740 So let's fold First pull those off like so and then we'll make sure that a user actually provided an 18 00:01:13,770 --> 00:01:15,420 email and a password. 19 00:01:15,420 --> 00:01:22,410 So we'll say that if there is no email or if there is no password then let's just give up we're going 20 00:01:22,410 --> 00:01:29,130 to return early we're gonna send back a response that they status once again a 422 and we'll send back 21 00:01:29,130 --> 00:01:33,690 an object with an error of must provide email and password 22 00:01:36,410 --> 00:01:40,850 so now we get past that check that we can start to go through the log and process the first thing we 23 00:01:40,850 --> 00:01:48,170 need to do is pick a user out of our database with the supplied email so we can do so by using the User 24 00:01:48,170 --> 00:01:50,510 model we have up here coming from mongoose. 25 00:01:50,570 --> 00:01:55,040 Remember this user model right here is how we interact with all the users that are stored inside of 26 00:01:55,040 --> 00:02:05,910 Mongo so in particular we're going to do an a wait with user dot find one find one method is going to 27 00:02:05,910 --> 00:02:13,900 taken an object in our case we want to look for some particular user with an email of email and of course 28 00:02:13,900 --> 00:02:19,660 as usual we can condense that down to just email like so now I'm using the await syntax right here because 29 00:02:19,660 --> 00:02:22,010 find one is going to take some time. 30 00:02:22,060 --> 00:02:27,490 Remember this is a asynchronous operation because Mongoose has to reach out to our Mongo DB database 31 00:02:27,730 --> 00:02:29,760 which just takes some amount of time. 32 00:02:30,040 --> 00:02:34,240 So I'm gonna make sure that I mark this function right here as being async so we can actually use that 33 00:02:34,300 --> 00:02:42,770 await syntax then we're going to assign whatever we get back to the user variable like so now we find 34 00:02:42,770 --> 00:02:48,110 one fails to find anything then user is going to be NULL which indicates that sorry we did not find 35 00:02:48,110 --> 00:02:53,510 a user with that given email so we'll do an immediate check right here and see if the user provided 36 00:02:54,110 --> 00:02:59,010 or whoever made the request provided an email that's not in use by any user inside of our database. 37 00:02:59,300 --> 00:03:05,760 So we'll see if there was not a user found then once again let's return early we'll set up a rez with 38 00:03:05,760 --> 00:03:16,620 the status of four or four and we'll say error email not found sorry we didn't find anyone with that 39 00:03:16,620 --> 00:03:22,620 given email so then after that we can attempt to go through that password comparison. 40 00:03:22,620 --> 00:03:28,110 So this user model right here is going to have an email and a hash insulted password tag attached to 41 00:03:28,110 --> 00:03:28,800 it. 42 00:03:28,800 --> 00:03:34,380 So we want to compare that password against the password that the user provided to our sign in method. 43 00:03:34,380 --> 00:03:41,130 So we're going to call a wait because remember we made this thing returning a promise user dot computer 44 00:03:41,190 --> 00:03:48,930 password and we'll pass in the supplied password by the user remember if something goes wrong with that 45 00:03:48,930 --> 00:03:54,210 comparison process or if the passwords don't match up then the promised return is going to be rejected. 46 00:03:54,240 --> 00:04:01,860 So we have to wrap this thing in a try catch statement so I'll put in a catch that's gonna receive whatever 47 00:04:01,860 --> 00:04:06,470 went wrong inside that era object and then inside of here if something went wrong. 48 00:04:06,540 --> 00:04:13,290 Well once again let's return early so we can do a rest status and we can put a status on here for 22 49 00:04:14,680 --> 00:04:19,320 or alternatively if you want to we could do a four or one of forbidden if we're trying to indicates 50 00:04:19,320 --> 00:04:23,960 that there's something kind of wrong with this underline request so we could do either a fortune in 51 00:04:23,950 --> 00:04:29,770 two or three for one of forbid entirely up to you and we'll send back once again an error of invalid 52 00:04:29,770 --> 00:04:33,370 password or email. 53 00:04:33,410 --> 00:04:37,810 Now I said just a little bit ago that whenever a handling authentication in general we want to give 54 00:04:37,810 --> 00:04:44,050 kind of opaque error messages so we might decide to actually use the same error message right here as 55 00:04:44,050 --> 00:04:49,090 the one whenever we do not find the user's email because technically right now if we send back the message 56 00:04:49,120 --> 00:04:54,070 email not found that could allow some malicious user to Detective someone to give an email address has 57 00:04:54,070 --> 00:04:55,510 ever signed up to our application. 58 00:04:55,960 --> 00:05:01,570 So we might decide to just use the same password in both cases just to hide whether or not someone with 59 00:05:01,570 --> 00:05:04,020 given e-mail has actually signed up. 60 00:05:04,030 --> 00:05:07,450 Now if we do that we would probably want to make sure that these status codes line up as well because 61 00:05:07,450 --> 00:05:10,980 otherwise there would once again be some kind of differentiating factor there. 62 00:05:10,990 --> 00:05:16,000 So I would just change them to be identical either for 22 for both or for a four for both or whatever 63 00:05:16,000 --> 00:05:17,870 else OK. 64 00:05:17,880 --> 00:05:23,280 So if we've now successfully compared our password then we want to make sure that we generate a Jason 65 00:05:23,280 --> 00:05:29,030 token once again and send it back so that the user can then authenticate themselves on future requests. 66 00:05:29,130 --> 00:05:36,370 So inside of here we will once again generate our token by calling JWT dot sign. 67 00:05:36,470 --> 00:05:42,890 We want to sign a payload with the user I.D. coming from the user model right here. 68 00:05:42,890 --> 00:05:48,980 And just like before we want to hash their I.D. So underscore I.D. And then remember the second argument 69 00:05:49,010 --> 00:05:55,360 is going to be our assigning key it must be consistent throughout all uses of JWT throughout our application. 70 00:05:55,430 --> 00:05:59,840 So I can make sure that I use the exact same key as before backup here inside of our previous request 71 00:05:59,840 --> 00:06:00,780 handler. 72 00:06:00,800 --> 00:06:08,910 So in my case it is my secret key so I'll go back down and provide that as the second argument to sign. 73 00:06:09,070 --> 00:06:12,170 Then finally we can send back the token that we generated. 74 00:06:12,170 --> 00:06:14,770 I'm just going to stay consistent with how we sent it back before. 75 00:06:14,780 --> 00:06:21,370 So I want to send back an object with a key of token and the value being the token so after we generate 76 00:06:21,370 --> 00:06:25,420 our token I'll do a resort send with token like so. 77 00:06:25,790 --> 00:06:26,980 And that should be it. 78 00:06:26,980 --> 00:06:29,410 So I think that we're now ready for a quick test. 79 00:06:29,410 --> 00:06:33,640 This video is actually going a little bit long but yeah let's just take a quick pause and I'll do a 80 00:06:33,640 --> 00:06:36,130 quick test of everything we just wrote in the next video. 81 00:06:36,220 --> 00:06:39,810 Make sure that we can sign up and then sign in with the given password. 82 00:06:39,910 --> 00:06:42,130 So quick pause and I'll see you in just a minute.