1 00:00:00,830 --> 00:00:05,790 We've now generated our Jason Webb token and sent it back to a user once they sign up for new account. 2 00:00:05,800 --> 00:00:10,050 So remember this token right here needs to be included in any follow up request. 3 00:00:10,070 --> 00:00:12,920 We're gonna use that token to identify a user. 4 00:00:12,920 --> 00:00:17,330 Let's first get started by adding in some additional codes where application to kind of validate that 5 00:00:17,330 --> 00:00:22,580 a user is sending us some token and if a user does send us a token that is valid will allow them to 6 00:00:22,670 --> 00:00:24,900 access some protected resource. 7 00:00:25,130 --> 00:00:29,840 So to get started I'm going to flip back over to my index J.S. file inside of here. 8 00:00:29,870 --> 00:00:33,420 I'm gonna go down to that little tester out we put together right here. 9 00:00:33,470 --> 00:00:39,060 So I want to say that we will only allow a user to access this test route if they have a valid Jason 10 00:00:39,080 --> 00:00:40,300 web token. 11 00:00:40,310 --> 00:00:42,990 So I want to add in some code somewhere inside my project. 12 00:00:43,070 --> 00:00:47,440 They'll make sure that a user can only access that if they have a valid token. 13 00:00:47,800 --> 00:00:54,790 So to do so inside my SDR see directory I'm gonna make a new folder called middle wears inside of here. 14 00:00:54,800 --> 00:01:02,290 We're going to create a new file called require off dot J.S. so inside this middleware or this file 15 00:01:02,350 --> 00:01:04,450 we're gonna write out a middleware function. 16 00:01:04,450 --> 00:01:10,100 This is a function that's going to take an incoming request and do some kind of pre processing on it. 17 00:01:10,150 --> 00:01:14,200 So inside of this middleware function we're going to make sure that the user includes some token and 18 00:01:14,200 --> 00:01:18,740 if they do we will allow them to access some given route inside our application. 19 00:01:18,760 --> 00:01:23,950 Otherwise if there is not a valid Jason web token we're going to reject the request and send an error 20 00:01:23,950 --> 00:01:25,440 back to the user. 21 00:01:25,620 --> 00:01:29,640 So to get started inside of here we're going to add in a couple of required statements. 22 00:01:29,740 --> 00:01:32,470 First off I'm going to require in that Jason web token library 23 00:01:35,630 --> 00:01:42,130 I'll also require in Mongoose and from the Mongoose library I'm going to get access to that user model 24 00:01:42,130 --> 00:01:42,790 that we created 25 00:01:47,130 --> 00:01:49,950 then inside of here we're going to define and export a function. 26 00:01:49,950 --> 00:01:53,820 So I'll say module dot exports is going to be an async function. 27 00:01:53,820 --> 00:01:58,230 Make sure you get a sync on their actually we don't need async on here. 28 00:01:58,230 --> 00:02:00,390 Let's take that async off my apologies. 29 00:02:00,440 --> 00:02:06,470 There's going to be just a plain function and it's going to be called with a request a response and 30 00:02:06,500 --> 00:02:07,970 a next function. 31 00:02:07,970 --> 00:02:13,220 So inside this middleware if we determine that a user does successfully have a Jason web token we call 32 00:02:13,220 --> 00:02:14,440 the next function right there. 33 00:02:14,480 --> 00:02:18,500 And that's essentially a signal that the request can move on to the next middleware inside of our chain 34 00:02:18,500 --> 00:02:23,870 of middleware as if there's no other middleware to run then we're going to go ahead and run our ultimate 35 00:02:23,870 --> 00:02:27,080 request handler which in our case is going to be that request handler. 36 00:02:27,080 --> 00:02:33,360 Right there now inside of here we can attempt to authenticate this user the first thing we have to do 37 00:02:33,390 --> 00:02:38,940 is kind of establish a mechanism of how the user is going to share that Jason web token with us. 38 00:02:38,970 --> 00:02:43,800 So for our application we're going to say that whenever a user attempts to authenticate themselves with 39 00:02:43,800 --> 00:02:49,520 us through a Jason web token they have to provide that token right there inside of a very special header. 40 00:02:49,670 --> 00:02:54,090 So inside a postman I'm going to create a new tab and we'll write out an example of what this header 41 00:02:54,090 --> 00:02:55,590 is going to look like. 42 00:02:55,650 --> 00:03:02,180 So I'm going to try making a get request to local host three thousand and then inside my head or section 43 00:03:02,270 --> 00:03:10,480 I'm going to add in a new header called authorisation and then its value will be the word bearer then 44 00:03:10,480 --> 00:03:13,770 a space and then we're going to put our token inside there. 45 00:03:13,790 --> 00:03:17,890 So going to flip back over to these sign up page really quickly I'm going to grab that token right there 46 00:03:17,920 --> 00:03:24,530 without the double quotes I'm going to copy that and then I'll put it in right after that bear right 47 00:03:24,530 --> 00:03:25,190 there. 48 00:03:25,370 --> 00:03:32,610 Like so now double check and make sure that your token does not have any double quotes on it because 49 00:03:32,610 --> 00:03:35,400 if it does this is not going to work correctly. 50 00:03:35,500 --> 00:03:40,690 So this is going to be the mechanism that we use to have a user share their token with our API. 51 00:03:40,870 --> 00:03:46,330 They have to include a header called authorisation and as a value they're going to provide bearer a 52 00:03:46,320 --> 00:03:48,610 space and then the token. 53 00:03:48,760 --> 00:03:54,210 Now anytime that our middleware runs right here we're going to inspect that incoming request we're going 54 00:03:54,210 --> 00:03:59,190 to look for a header called authorization and if a user has provided that header we're going to try 55 00:03:59,190 --> 00:04:04,810 to extract the Jason web token from it and validate that is a genuine token. 56 00:04:04,890 --> 00:04:12,570 So to do so we're going to first pull off the authorization header from wreck dot headers so whenever 57 00:04:12,570 --> 00:04:17,550 an incoming request comes into our server any headers that are attached that requests will be placed 58 00:04:17,550 --> 00:04:22,380 inside this headers property so we're going to pull off the authorization header. 59 00:04:22,380 --> 00:04:25,160 You'll notice that I used a lowercase to a right here. 60 00:04:25,170 --> 00:04:32,080 Even though we provided a uppercase authorization over here so whenever a request comes into express 61 00:04:32,200 --> 00:04:38,590 it automatically down cases or lower cases any header names so casually authorization from our request 62 00:04:38,850 --> 00:04:45,150 will turn into a lowercase a authorization inside of our headers object so then we can immediately say 63 00:04:46,340 --> 00:04:51,830 if a user did not provide an authorization header then this must not be a valid request. 64 00:04:51,830 --> 00:04:56,750 In other words the user has not attempted to prove that they are who they say they're going to immediately 65 00:04:56,750 --> 00:05:00,620 return and I'll return resident status with. 66 00:05:00,630 --> 00:05:07,710 How about like a for a one which is a forbidden air and we'll send back an error message of something 67 00:05:07,710 --> 00:05:09,980 like You must be logged in. 68 00:05:10,050 --> 00:05:10,500 Like so 69 00:05:14,260 --> 00:05:16,220 many claps at sidebars we can see the whole line. 70 00:05:16,240 --> 00:05:18,600 There we go okay. 71 00:05:18,630 --> 00:05:22,820 So if a user gets passed that check then they must have provided a valid token. 72 00:05:22,820 --> 00:05:27,950 So now we can try to extract that token out of this authorization header so to do so we'll say cons 73 00:05:27,960 --> 00:05:34,360 token is going to be authorization just to be clear authorization right there. 74 00:05:34,440 --> 00:05:39,390 Let's put a little note right here actually about right underneath authorization to put a little note 75 00:05:39,390 --> 00:05:43,770 to myself and just say authorization is going to be something like a string that says bearer and then 76 00:05:43,770 --> 00:05:46,000 my Jason web token. 77 00:05:46,020 --> 00:05:48,820 So we need to extract just that token by itself. 78 00:05:48,820 --> 00:05:54,970 So to do so we can say authorization dot replace bearer or then put a space right there. 79 00:05:55,020 --> 00:05:59,720 So make sure you get a space right after the word there and we will replace that with an empty string. 80 00:05:59,780 --> 00:06:05,000 So that should leave us with just the token right there. 81 00:06:05,020 --> 00:06:12,220 So now to validate this token we can call JWT dot verify the first argument is going to be the token 82 00:06:12,220 --> 00:06:17,620 we want to validate the second argument is going to be our secret key and remember our secret key right 83 00:06:17,620 --> 00:06:24,080 now or at least mine is my secret key all capital capitals with underscores between each word. 84 00:06:24,130 --> 00:06:27,660 So I going to put that into JWT dot verify as the second argument. 85 00:06:28,450 --> 00:06:33,520 And then the third argument will be my callback function that will be invoked after Jason web token 86 00:06:33,580 --> 00:06:36,680 has done some validation on that token. 87 00:06:36,700 --> 00:06:38,980 So this is where we want our async. 88 00:06:39,130 --> 00:06:41,260 We're gonna make a a scene callback right here. 89 00:06:41,260 --> 00:06:44,020 Remember I accidently put the async keyword up there my mistake. 90 00:06:44,020 --> 00:06:51,130 So I want async and then my function and this callback function will be called with an error if something 91 00:06:51,130 --> 00:06:57,190 went wrong with the verification process and if everything went OK we'll get our payload so payload 92 00:06:57,190 --> 00:07:00,850 right here is going to be whatever information we stuck in to our Jason Webb token. 93 00:07:00,940 --> 00:07:06,280 So in our case it's going to be an object like that right there in object with a user I.D. and that's 94 00:07:06,280 --> 00:07:10,860 the idea the user as they're stored inside of our database. 95 00:07:10,900 --> 00:07:16,250 Now inside this callback we'll immediately take a look at that air object so we'll say if there was 96 00:07:16,250 --> 00:07:22,790 an error if something went wrong then let's return immediately so we can return a resit status for one 97 00:07:23,570 --> 00:07:29,720 and we'll once again just send back an error message as something like You must be logged in we could 98 00:07:29,720 --> 00:07:33,260 potentially say that the user provided an invalid token. 99 00:07:33,260 --> 00:07:39,500 But in general we usually tried to give users kind of opaque error messages whenever it comes to a verification 100 00:07:39,530 --> 00:07:45,440 or authorization errors because that gives a malicious user that much less information about how they 101 00:07:45,440 --> 00:07:53,280 can kind of circumvent our authorization checks OK it's now after we've verified and made sure that 102 00:07:53,280 --> 00:07:59,440 the user provided a legitimate token we can then attempt to extract the user's idea from that payload. 103 00:07:59,440 --> 00:08:08,730 So we'll say const user I.D. is coming from payload now we can use that user idea right there to look 104 00:08:08,730 --> 00:08:11,760 up our user inside of our users collection from mongo DB. 105 00:08:12,240 --> 00:08:20,610 So to do so we can say const user is going to be a weight user model so capital you user find by I.D. 106 00:08:21,060 --> 00:08:22,790 and we'll pass in our user I.D.. 107 00:08:23,620 --> 00:08:27,850 So that's going to tell Mongoose to go and take a look at our Mongo DB collection. 108 00:08:27,980 --> 00:08:33,680 It's going to attempt to find a user inside there with a given I.D. and once it finds it it's going 109 00:08:33,680 --> 00:08:35,920 to assign that user to this user variable. 110 00:08:35,930 --> 00:08:42,720 So now we know exactly who made the request so now we're going to take that user and assign it to our 111 00:08:42,780 --> 00:08:43,880 req object. 112 00:08:43,890 --> 00:08:47,220 Remember this Middleware is called with our incoming request. 113 00:08:47,220 --> 00:08:51,450 Chances are that some other request handlers inside our application might want to have some information 114 00:08:51,450 --> 00:08:56,970 about the given user so we'll attach that user model directly to that request object so that any other 115 00:08:56,970 --> 00:09:03,900 request handler inside of rap can very easily get access to this user model so we'll take that user 116 00:09:04,170 --> 00:09:09,420 and we'll assign it to the rec object on the user property and then after that we've done everything 117 00:09:09,420 --> 00:09:10,780 we need to do inside of our middleware. 118 00:09:10,800 --> 00:09:14,370 So we will call next which is a sign that our middleware is all done running. 119 00:09:14,400 --> 00:09:16,980 We can call the next middleware inside of our chain of middleware. 120 00:09:17,890 --> 00:09:18,110 Okay. 121 00:09:18,150 --> 00:09:18,830 So that's pretty much it. 122 00:09:18,840 --> 00:09:23,580 That's our entire Jason web token middleware that's going to make sure that a user provides a token 123 00:09:23,640 --> 00:09:26,520 whenever they make some kind of request to us. 124 00:09:26,520 --> 00:09:29,650 So now to actually use this thing we'll save this file. 125 00:09:29,810 --> 00:09:32,780 I'm going to require it back into the index J.S. file. 126 00:09:32,810 --> 00:09:43,580 So back inside of index dot J.S. at the very top I will require require off we're going to require that 127 00:09:44,330 --> 00:09:47,180 from the middle where's require auth file 128 00:09:50,630 --> 00:09:53,670 and now we can make use of this inside of any of our different quest handlers. 129 00:09:53,690 --> 00:09:58,340 So remember in our case we want to make sure that we secure this default route right here. 130 00:09:58,340 --> 00:10:02,970 So to use that middleware we'll provide it right before that second request handler. 131 00:10:03,110 --> 00:10:09,320 It's all say require off like so so now whenever someone makes a request to our route route we're going 132 00:10:09,320 --> 00:10:10,700 to first run that middleware. 133 00:10:10,750 --> 00:10:15,740 We're gonna make sure that the user provided a valid Jason web token and if they did well then allow 134 00:10:15,740 --> 00:10:21,290 them to actually access that given route right there that route handler if a valid token was not provided 135 00:10:21,530 --> 00:10:26,100 then the request will be automatically rejected and the user will see an error message. 136 00:10:26,120 --> 00:10:29,990 So now just to make sure that everything really is working correctly rather than just sending back a 137 00:10:29,990 --> 00:10:35,630 message of hi there let's change this into a template string by using back ticks and we'll put inside 138 00:10:35,630 --> 00:10:45,070 of your your email and then I'll put down a set of curly braces like so is req dot user dot email. 139 00:10:45,390 --> 00:10:49,570 So remember we assigned that user model or that user instance to the Rec object. 140 00:10:49,570 --> 00:10:54,250 So we're gonna take that thing and just print out the user's email inside our response and so that will 141 00:10:54,310 --> 00:10:58,940 allow us to really validate that we've identified who a user is. 142 00:10:58,960 --> 00:10:59,240 Okay. 143 00:10:59,270 --> 00:11:05,470 Let's save this and give it a quick test it's going to flip back over to postman back over here. 144 00:11:05,470 --> 00:11:12,010 I'm going to attempt to make a request a get request to local who's 3000 with a header of capital a 145 00:11:12,010 --> 00:11:17,860 authorization and a bearer then a space and then my entire JS on the web token I'm going to send that 146 00:11:18,190 --> 00:11:21,490 and I'll see your email is blah blah blah. 147 00:11:21,490 --> 00:11:23,440 So looks like that definitely work successfully. 148 00:11:23,440 --> 00:11:30,370 Our middleware has extracted that Jason web token extracted the user I.D. out of it use that user I.D. 149 00:11:30,370 --> 00:11:35,440 to find the appropriate user inside of our database and then assign that user model to our rec object 150 00:11:35,650 --> 00:11:36,250 and then our right. 151 00:11:36,280 --> 00:11:40,720 Our request handler ultimately printed out some information about that user incented back inside the 152 00:11:40,720 --> 00:11:45,060 response now to make sure that everything is really working correctly. 153 00:11:45,060 --> 00:11:48,540 I'm going to try making a little change to this chase on web token. 154 00:11:48,540 --> 00:11:53,880 If we change any character inside of here and even the smallest way it's going to make the Jason web 155 00:11:53,880 --> 00:11:57,070 token fail to be validated by our server. 156 00:11:57,090 --> 00:12:01,140 So that means that our server is not going to trust the information inside of here. 157 00:12:01,140 --> 00:12:06,180 So to make a small change I'm just gonna remove that leading e character on there I'll just delete e 158 00:12:06,270 --> 00:12:06,960 like so. 159 00:12:06,950 --> 00:12:10,990 So one very small change that I can immediately revert if I need to. 160 00:12:11,120 --> 00:12:14,570 It's now that I've modified that Jason web token I'll send this again. 161 00:12:14,670 --> 00:12:17,190 And now I see an error that says you must be logged in. 162 00:12:17,190 --> 00:12:19,970 So now the Jason web token is no longer valid. 163 00:12:19,980 --> 00:12:21,570 So we're saying hey get out of here. 164 00:12:21,600 --> 00:12:24,430 We don't want you inside of our server okay. 165 00:12:24,470 --> 00:12:25,940 So it looks like it's working perfectly. 166 00:12:25,940 --> 00:12:31,150 If I put the E back on there once again I can make the request again and I now see my email again. 167 00:12:31,660 --> 00:12:31,930 OK. 168 00:12:31,970 --> 00:12:32,800 So it looks great. 169 00:12:32,800 --> 00:12:35,660 It looks like we now have the ability to actually validate users. 170 00:12:35,660 --> 00:12:38,000 We're making a request to our API. 171 00:12:38,100 --> 00:12:40,110 It's now we've got this all put together. 172 00:12:40,310 --> 00:12:42,280 Let's kind of go back in time here. 173 00:12:42,290 --> 00:12:47,040 I said that we were going to fix up that plain text password that we were storing inside of Mongo DB. 174 00:12:47,060 --> 00:12:51,620 Remember if we go back to our Mongo DB instance over here we've got that plaintext password. 175 00:12:51,620 --> 00:12:54,120 And I'd said that we're going to fix that up but we never did. 176 00:12:54,140 --> 00:12:55,270 Let's take a quick pause right here. 177 00:12:55,280 --> 00:12:59,300 When we come back the next video we're gonna make sure that we don't store our passwords in plain text 178 00:12:59,300 --> 00:12:59,690 anymore.