1 00:00:00,660 --> 00:00:01,492 -: In the last section, 2 00:00:01,492 --> 00:00:02,670 we discussed the need to have 3 00:00:02,670 --> 00:00:04,620 some authentication layer, 4 00:00:04,620 --> 00:00:05,820 that our requests are gonna hit, 5 00:00:05,820 --> 00:00:08,340 before they go to our actual protected routes 6 00:00:08,340 --> 00:00:10,980 or our protected controllers. 7 00:00:10,980 --> 00:00:12,390 We said that we were gonna use a library 8 00:00:12,390 --> 00:00:14,520 called Passport to make that happen, 9 00:00:14,520 --> 00:00:16,470 and we also pulled in that library, 10 00:00:16,470 --> 00:00:17,790 and then we installed it, 11 00:00:17,790 --> 00:00:20,550 and created this passport.js file. 12 00:00:20,550 --> 00:00:21,780 Is a quick reminder, 13 00:00:21,780 --> 00:00:26,010 the purpose of passport is we want to hit this kind of... 14 00:00:26,010 --> 00:00:27,240 we want to answer this question, 15 00:00:27,240 --> 00:00:28,980 is our user logged in or not, 16 00:00:28,980 --> 00:00:31,050 before they hit these controllers, right? 17 00:00:31,050 --> 00:00:32,880 We want to answer that ahead of time 18 00:00:32,880 --> 00:00:34,740 and we wanna centralize all that logic; 19 00:00:34,740 --> 00:00:36,870 make sure it only occurs in one place 20 00:00:36,870 --> 00:00:39,060 as opposed to checking for it all the time 21 00:00:39,060 --> 00:00:41,430 inside of our controllers themselves. 22 00:00:41,430 --> 00:00:42,840 So let's talk a little bit more about 23 00:00:42,840 --> 00:00:45,120 exactly what's gonna go on inside of this file. 24 00:00:45,120 --> 00:00:47,970 I'm gonna pull another diagram up on the screen. 25 00:00:47,970 --> 00:00:50,190 So this one is kind of an exploded view 26 00:00:50,190 --> 00:00:52,230 of the diagram that we were just looking at. 27 00:00:52,230 --> 00:00:54,870 We have some incoming request, 28 00:00:54,870 --> 00:00:57,750 it's going to hit our passport library 29 00:00:57,750 --> 00:00:59,340 where we're going to answer the question 30 00:00:59,340 --> 00:01:01,350 is this user logged in or not? 31 00:01:01,350 --> 00:01:03,780 And then it's gonna go onto the route handler 32 00:01:03,780 --> 00:01:05,643 if the user is currently logged in. 33 00:01:07,320 --> 00:01:09,600 So the passport library that we installed, 34 00:01:09,600 --> 00:01:11,430 we didn't only install passport, right? 35 00:01:11,430 --> 00:01:16,320 We also installed this library called passport-jwt. 36 00:01:16,320 --> 00:01:18,863 So passport is not just a library, 37 00:01:18,863 --> 00:01:22,080 it is a little bit more of an ecosystem. 38 00:01:22,080 --> 00:01:24,540 It is an ecosystem formed by what we call 39 00:01:24,540 --> 00:01:27,150 or referred to as strategies. 40 00:01:27,150 --> 00:01:30,510 And so in this diagram, I've listed two possible strategies. 41 00:01:30,510 --> 00:01:32,220 Passport strategy number one 42 00:01:32,220 --> 00:01:34,770 and passport strategy number two. 43 00:01:34,770 --> 00:01:37,380 In passport, a strategy is a method 44 00:01:37,380 --> 00:01:40,080 for authenticating a user. 45 00:01:40,080 --> 00:01:42,510 So we imported or we installed 46 00:01:42,510 --> 00:01:47,310 one strategy called passport-jwt 47 00:01:47,310 --> 00:01:50,370 that attempts to validate or authenticate a user 48 00:01:50,370 --> 00:01:52,980 by using a JSON Web Token. 49 00:01:52,980 --> 00:01:56,250 We could also install a strategy that would attempt to 50 00:01:56,250 --> 00:01:59,730 verify a user given a username and password. 51 00:01:59,730 --> 00:02:01,830 There are many many many different passport 52 00:02:01,830 --> 00:02:03,063 strategies out there. 53 00:02:03,930 --> 00:02:05,400 And if you want to take a look, 54 00:02:05,400 --> 00:02:07,230 you can go to the passport official website 55 00:02:07,230 --> 00:02:08,669 and look all the different ones they have. 56 00:02:08,669 --> 00:02:10,590 There are strategies for handling like 57 00:02:10,590 --> 00:02:14,760 Facebook login or Twitter or GitHub or Google Login. 58 00:02:14,760 --> 00:02:18,240 All these different login strategies that get encapsulated 59 00:02:18,240 --> 00:02:21,753 in a single library that works as a plugin to passport. 60 00:02:22,590 --> 00:02:25,440 So we grabbed the library specifically 61 00:02:25,440 --> 00:02:29,463 for helping us authenticate users using JWT. 62 00:02:31,500 --> 00:02:33,570 So that's what we're going to be working on in this section. 63 00:02:33,570 --> 00:02:37,260 We're going to set up this JWT strategy that we installed. 64 00:02:37,260 --> 00:02:39,990 We're gonna pass some additional options or just do some 65 00:02:39,990 --> 00:02:42,140 a little bit of configuration inside of it. 66 00:02:43,020 --> 00:02:44,550 So here's what we're going to do, 67 00:02:44,550 --> 00:02:48,220 we're going to first create some number of jwtOptions 68 00:02:49,560 --> 00:02:51,940 to kind of configure this strategy 69 00:02:53,190 --> 00:02:54,393 and put a comment on it. 70 00:02:56,490 --> 00:02:59,973 Set up options for JWT Strategy. 71 00:03:01,320 --> 00:03:04,960 We are then going to create JWT Strategy 72 00:03:06,210 --> 00:03:07,800 and finally, 73 00:03:07,800 --> 00:03:09,450 tell Passport 74 00:03:09,450 --> 00:03:11,880 to use this strategy. 75 00:03:11,880 --> 00:03:14,343 Okay, so kinda a three-step process here. 76 00:03:16,680 --> 00:03:20,550 Let's leave these options as just an empty object right now, 77 00:03:20,550 --> 00:03:22,410 just because it's not gonna make too much sense 78 00:03:22,410 --> 00:03:24,420 if we just go ahead and start throwing data 79 00:03:24,420 --> 00:03:25,253 in here at the start. 80 00:03:25,253 --> 00:03:26,760 Let's write some other code first 81 00:03:26,760 --> 00:03:28,020 and then talk about the options 82 00:03:28,020 --> 00:03:29,973 that we are gonna want to pass in here. 83 00:03:31,110 --> 00:03:34,980 So let's start by creating our JWT strategy. 84 00:03:34,980 --> 00:03:37,290 We're going to create 85 00:03:37,290 --> 00:03:39,930 a jwtLogin object, 86 00:03:39,930 --> 00:03:42,583 that is going to be a new JwtStrategy. 87 00:03:46,200 --> 00:03:49,380 The first argument to this constructor 88 00:03:49,380 --> 00:03:51,480 is going to be our jwtOptions 89 00:03:51,480 --> 00:03:53,280 which we created right here. 90 00:03:53,280 --> 00:03:55,320 And then the second argument is going to 91 00:03:55,320 --> 00:03:57,150 be a function that's going to be called 92 00:03:57,150 --> 00:04:00,270 whenever a user tries to log in with a JWT 93 00:04:00,270 --> 00:04:05,063 or whenever we need to authenticate a user with a JWT Token. 94 00:04:07,110 --> 00:04:10,380 The first argument to this is a payload 95 00:04:10,380 --> 00:04:12,690 and the second is done. 96 00:04:12,690 --> 00:04:15,780 So you might be asking, hopefully you're asking, 97 00:04:15,780 --> 00:04:18,029 well, of course there's a lot of really weird code 98 00:04:18,029 --> 00:04:19,230 on the screen right now. 99 00:04:20,100 --> 00:04:21,029 You might be wondering, 100 00:04:21,029 --> 00:04:22,710 what in the world are these two arguments? 101 00:04:22,710 --> 00:04:24,120 Where are they coming from? 102 00:04:24,120 --> 00:04:29,070 So the payload right here is the decoded JWT token. 103 00:04:29,070 --> 00:04:30,660 Remember in the last, 104 00:04:30,660 --> 00:04:32,670 or just one or two sections ago 105 00:04:32,670 --> 00:04:35,070 in the authentication controller, 106 00:04:35,070 --> 00:04:39,270 it created our JWT Token and we assigned a sub 107 00:04:39,270 --> 00:04:43,920 or subject and issued at timestamp on the token. 108 00:04:43,920 --> 00:04:46,980 This was the token's payload right here. 109 00:04:46,980 --> 00:04:49,263 And so when we get a payload back, 110 00:04:50,880 --> 00:04:54,570 the payload coming from the JWT strategy is going to be 111 00:04:54,570 --> 00:04:56,880 that user ID and that timestamp. 112 00:04:56,880 --> 00:05:00,273 So it's gonna have a sub-property and an issued at property. 113 00:05:01,920 --> 00:05:05,160 The second item on here, done is a callback function 114 00:05:05,160 --> 00:05:07,530 that we need to call depending on whether or not 115 00:05:07,530 --> 00:05:11,640 we are able to successfully authenticate this user. 116 00:05:11,640 --> 00:05:14,790 Okay, so basically what we wanna return from this callback. 117 00:05:14,790 --> 00:05:15,933 So we wanna return, 118 00:05:17,010 --> 00:05:18,120 or I shouldn't say return 119 00:05:18,120 --> 00:05:20,910 but what we want to accomplish in here, what we wanna do; 120 00:05:20,910 --> 00:05:22,840 we want to see if 121 00:05:23,730 --> 00:05:25,410 the user ID 122 00:05:25,410 --> 00:05:28,980 in the payload exists 123 00:05:28,980 --> 00:05:30,543 in our database. 124 00:05:31,620 --> 00:05:33,060 If it does, 125 00:05:33,060 --> 00:05:33,893 call 126 00:05:35,070 --> 00:05:37,180 done with that user 127 00:05:38,130 --> 00:05:39,363 otherwise, 128 00:05:41,520 --> 00:05:45,000 call done without a user object. 129 00:05:45,000 --> 00:05:47,910 Alright, So this is what we're trying to accomplish here. 130 00:05:47,910 --> 00:05:51,090 What's gonna happen is if we successfully find a user 131 00:05:51,090 --> 00:05:53,610 with the ID that we're getting from the Token 132 00:05:53,610 --> 00:05:55,950 'cause remember we encoded the user's ID 133 00:05:55,950 --> 00:05:58,470 as the subject property on the Token. 134 00:05:58,470 --> 00:06:00,240 If we can find that user, 135 00:06:00,240 --> 00:06:02,910 we're going to pass it to this done callback 136 00:06:02,910 --> 00:06:05,400 and it's gonna say, okay we found the user, 137 00:06:05,400 --> 00:06:08,430 it's a valid user, here you go, passport, go to your thing. 138 00:06:08,430 --> 00:06:10,950 So in other words, we're saying they are now authenticated, 139 00:06:10,950 --> 00:06:12,573 they are allowed to have access. 140 00:06:13,800 --> 00:06:16,170 If we cannot find a user with that ID, 141 00:06:16,170 --> 00:06:19,110 we're going to call this done function 142 00:06:19,110 --> 00:06:21,360 without a user object which indicates, 143 00:06:21,360 --> 00:06:23,370 no, this person is not authenticated, 144 00:06:23,370 --> 00:06:25,200 they're not valid, don't let them in. 145 00:06:25,200 --> 00:06:27,480 Alright, so let's write the code out 146 00:06:27,480 --> 00:06:29,583 for these different cases. 147 00:06:31,110 --> 00:06:35,310 On our payload, we have the sub-property, which is the ID. 148 00:06:35,310 --> 00:06:37,230 So let's use our user model 149 00:06:37,230 --> 00:06:39,510 which we already imported at the top. 150 00:06:39,510 --> 00:06:42,000 We'll look through all of our different users 151 00:06:42,000 --> 00:06:45,633 and we'll try to find a user with this given ID. 152 00:06:48,330 --> 00:06:49,473 In the callback, 153 00:06:51,607 --> 00:06:54,390 for the fine by ID call, 154 00:06:54,390 --> 00:06:56,280 we're going to get two arguments. 155 00:06:56,280 --> 00:06:57,603 Err and user. 156 00:06:58,470 --> 00:06:59,370 Remember in this case, 157 00:06:59,370 --> 00:07:03,780 err is gonna be populated only if the search failed. 158 00:07:03,780 --> 00:07:05,910 So like if we don't have access to the database 159 00:07:05,910 --> 00:07:07,320 or something like that. 160 00:07:07,320 --> 00:07:09,300 So if err 161 00:07:09,300 --> 00:07:10,170 return, 162 00:07:10,170 --> 00:07:11,073 done. 163 00:07:12,210 --> 00:07:13,743 Err and false. 164 00:07:16,860 --> 00:07:20,340 In this case, the first argument to done is an error object. 165 00:07:20,340 --> 00:07:23,460 And the second argument should be our user object, 166 00:07:23,460 --> 00:07:24,360 if we found one. 167 00:07:24,360 --> 00:07:26,700 In this case, we would've not found a user 168 00:07:26,700 --> 00:07:30,360 and so we're going to return done with an error object. 169 00:07:30,360 --> 00:07:31,200 And false. 170 00:07:31,200 --> 00:07:32,940 False meaning no, we didn't find a user. 171 00:07:32,940 --> 00:07:35,850 So this person, whoever gave, just made a request. 172 00:07:35,850 --> 00:07:38,800 Whoever's giving us this token, they are not authenticated. 173 00:07:40,200 --> 00:07:43,353 Next, we'll say if we found a user, 174 00:07:44,430 --> 00:07:48,033 call done without an err and that user. 175 00:07:49,440 --> 00:07:51,603 Otherwise, if we did not find a user, 176 00:07:52,920 --> 00:07:54,010 call done 177 00:07:54,930 --> 00:07:57,540 with null because there's not an error, 178 00:07:57,540 --> 00:07:58,920 but call it with false. 179 00:07:58,920 --> 00:08:01,470 So we know that hey, you know, there wasn't an error 180 00:08:01,470 --> 00:08:03,930 in the process of searching for the user 181 00:08:03,930 --> 00:08:05,460 but we did not find a user. 182 00:08:05,460 --> 00:08:07,530 So those would be two separate error cases, 183 00:08:07,530 --> 00:08:10,170 one in which the search failed to occur, 184 00:08:10,170 --> 00:08:11,850 and one in which we did a search 185 00:08:11,850 --> 00:08:13,503 but we couldn't find a user. 186 00:08:14,730 --> 00:08:16,590 Okay, so this is step one right here. 187 00:08:16,590 --> 00:08:19,830 This is look for a user that already exists 188 00:08:19,830 --> 00:08:22,233 with our very particular payload ID. 189 00:08:23,130 --> 00:08:25,590 If they do exist, call done 190 00:08:25,590 --> 00:08:29,160 which is a callback as the part of passport. 191 00:08:29,160 --> 00:08:31,860 And let passport know who the user is. 192 00:08:31,860 --> 00:08:34,350 Otherwise tell passport, no, we didn't find anyone. 193 00:08:34,350 --> 00:08:36,212 This person is not authenticated. 194 00:08:38,100 --> 00:08:40,890 Alright, so before we without turning this 195 00:08:40,890 --> 00:08:42,419 into a super long section, 196 00:08:42,419 --> 00:08:44,159 let's continue in the next section 197 00:08:44,159 --> 00:08:47,010 and talk about what the JWT options up here are. 198 00:08:47,010 --> 00:08:48,270 And we'll do another run through 199 00:08:48,270 --> 00:08:50,250 on all the logic in here and you know, 200 00:08:50,250 --> 00:08:51,720 again what we're trying to accomplish 201 00:08:51,720 --> 00:08:53,400 with this strategy overall. 202 00:08:53,400 --> 00:08:55,200 So I'll see you in the next section.