All language subtitles for 014 Password Reset Functionality_ Setting New Password_Downloadly.ir_en

af Afrikaans
sq Albanian
am Amharic
ar Arabic Download
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bn Bengali
bs Bosnian
bg Bulgarian
ca Catalan
ceb Cebuano
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
tl Filipino
fi Finnish
fr French
fy Frisian
gl Galician
ka Georgian
de German
el Greek
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
km Khmer
ko Korean
ku Kurdish (Kurmanji)
ky Kyrgyz
lo Lao
la Latin
lv Latvian
lt Lithuanian
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mn Mongolian
my Myanmar (Burmese)
ne Nepali
no Norwegian
ps Pashto
fa Persian Download
pl Polish
pt Portuguese
pa Punjabi
ro Romanian
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
st Sesotho
sn Shona
sd Sindhi
si Sinhala
sk Slovak
sl Slovenian
so Somali
es Spanish
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
te Telugu
th Thai
tr Turkish
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
or Odia (Oriya)
rw Kinyarwanda
tk Turkmen
tt Tatar
ug Uyghur
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated: 1 00:00:01,210 --> 00:00:04,650 And now let's finally create the last part 2 00:00:04,650 --> 00:00:07,010 of the Password Reset Functionality, 3 00:00:07,010 --> 00:00:10,593 where we actually set the new password for the user. 4 00:00:12,250 --> 00:00:15,900 And so, just like before, let's start by defining the steps 5 00:00:15,900 --> 00:00:19,713 that we're gonna take for this resetPassword flow. 6 00:00:21,240 --> 00:00:26,240 So, first off, get user based on the token. 7 00:00:30,350 --> 00:00:35,350 Then as the second step, we will set the new password 8 00:00:35,890 --> 00:00:40,153 but only if token has not expired, 9 00:00:42,070 --> 00:00:44,040 and there is a user. 10 00:00:44,040 --> 00:00:48,633 So in that case, set the new password. 11 00:00:51,580 --> 00:00:55,250 Then after that, we need to update 12 00:00:57,210 --> 00:01:01,000 the changedPasswordAt property 13 00:01:04,080 --> 00:01:05,403 for the current user, 14 00:01:07,320 --> 00:01:10,533 and then finally, as is usual in this functionality, 15 00:01:11,680 --> 00:01:12,853 is to log the user in. 16 00:01:14,010 --> 00:01:18,840 Basically, send the JSON Web Token to the client. 17 00:01:18,840 --> 00:01:22,733 Okay, so a lot of work to do, and so let's get started. 18 00:01:23,950 --> 00:01:27,493 And so, remember from the last video, that the reset token 19 00:01:27,493 --> 00:01:30,450 that is actually sent in the URL 20 00:01:30,450 --> 00:01:33,110 is this non-encrypted token here. 21 00:01:33,110 --> 00:01:34,723 So, actually this one. 22 00:01:35,570 --> 00:01:37,810 But the one that we have in the database 23 00:01:37,810 --> 00:01:39,680 is the encrypted one. 24 00:01:39,680 --> 00:01:42,580 So we talked about that before, and so what we now 25 00:01:42,580 --> 00:01:44,910 need to do, is to basically encrypt 26 00:01:44,910 --> 00:01:46,630 the original token again, 27 00:01:46,630 --> 00:01:49,240 so we can then compare it with the one that is stored, 28 00:01:49,240 --> 00:01:51,433 so the encrypted one in the database. 29 00:01:52,870 --> 00:01:55,110 So, we actually did something similar before 30 00:01:55,110 --> 00:01:57,890 with the password, but with the password, 31 00:01:57,890 --> 00:02:01,010 we couldn't compare it as easily as we can with this one, 32 00:02:01,010 --> 00:02:02,650 again because for the password 33 00:02:02,650 --> 00:02:05,770 we used the quite complex bcrypt algorithm, 34 00:02:05,770 --> 00:02:07,490 which in this case, we didn't. 35 00:02:07,490 --> 00:02:09,750 So, here it's very straightforward. 36 00:02:09,750 --> 00:02:13,040 All we need to do again, is to encrypt the token 37 00:02:13,040 --> 00:02:17,390 and compare it with the encrypted one in the database. 38 00:02:17,390 --> 00:02:22,390 So, let's say hashedToken, and so we will actually now 39 00:02:23,670 --> 00:02:26,813 need the crypto package here as well. 40 00:02:31,730 --> 00:02:36,167 Const crypto and then require('crypto'). 41 00:02:41,280 --> 00:02:42,123 Now right. 42 00:02:43,780 --> 00:02:47,593 Then let's go back, and so, 43 00:02:48,750 --> 00:02:51,610 we use crypto.createHash. 44 00:02:53,070 --> 00:02:57,973 Remember, then the name of the algorithm again, sha256, 45 00:02:58,910 --> 00:03:03,910 then .update, basically for the place, for the string 46 00:03:04,140 --> 00:03:06,040 that we want to hash. 47 00:03:06,040 --> 00:03:10,110 And so, that one is, remember in req.params. 48 00:03:10,110 --> 00:03:14,083 So we then use this one for a long time .token. 49 00:03:15,060 --> 00:03:17,950 And so again, it is a parameter, 50 00:03:17,950 --> 00:03:22,233 because we specified so here in the URL, so like this. 51 00:03:23,250 --> 00:03:26,470 So, it's now a parameter called token. 52 00:03:26,470 --> 00:03:31,470 And so, of course, here it's req.params.token. 53 00:03:31,804 --> 00:03:34,790 And then, finally, we also need to say digest 54 00:03:36,840 --> 00:03:38,633 and convert it to hexadecimal. 55 00:03:40,380 --> 00:03:42,760 Now this is basically the same 56 00:03:42,760 --> 00:03:46,180 as we had before, where we encrypted the original one, 57 00:03:46,180 --> 00:03:49,520 and so we could refactor this into its own function, 58 00:03:49,520 --> 00:03:51,693 but let's just keep it simple here. 59 00:03:54,240 --> 00:03:58,930 So, now let's actually get the user based on this token. 60 00:03:58,930 --> 00:04:01,060 Because that is actually, the only thing 61 00:04:01,060 --> 00:04:03,530 that we know about the user right now. 62 00:04:03,530 --> 00:04:07,080 We have no email, we have nothing, so this token 63 00:04:07,080 --> 00:04:10,130 is the only thing that can identify the user. 64 00:04:10,130 --> 00:04:12,520 And so we can now, basically, query the database 65 00:04:12,520 --> 00:04:14,170 for this token. 66 00:04:14,170 --> 00:04:17,303 And it will then find the user which has this token. 67 00:04:19,230 --> 00:04:24,230 So, await, as we already know, and then User.findOne. 68 00:04:27,790 --> 00:04:31,213 So, that property is called passwordResetToken 69 00:04:32,090 --> 00:04:36,117 and we are looking for the hashedToken. 70 00:04:37,940 --> 00:04:42,220 And now of course, we need to declare it as async 71 00:04:43,150 --> 00:04:44,643 and prep it into catchAsync. 72 00:04:48,557 --> 00:04:51,810 Give it a save, that should fix this bug, 73 00:04:51,810 --> 00:04:53,950 and indeed it does. 74 00:04:53,950 --> 00:04:56,950 So, this will find user who has the token 75 00:04:56,950 --> 00:04:59,100 that will send via URL. 76 00:04:59,100 --> 00:05:00,910 But, right now, we're not taking 77 00:05:00,910 --> 00:05:04,090 the token expiration date into consideration. 78 00:05:04,090 --> 00:05:06,000 And so how could we do that? 79 00:05:06,000 --> 00:05:09,020 Well, basically, what we want is to check 80 00:05:09,020 --> 00:05:11,860 if the passwordResetExpires property 81 00:05:11,860 --> 00:05:13,723 is greater than right now. 82 00:05:14,890 --> 00:05:17,350 Because if the expires date is greater than now, 83 00:05:17,350 --> 00:05:20,420 it means it's in the future, which in turn means, 84 00:05:20,420 --> 00:05:22,313 that it hasn't yet expired. 85 00:05:23,180 --> 00:05:24,850 And so, that's a very easy way 86 00:05:24,850 --> 00:05:28,343 in which we can actually do this right with this query. 87 00:05:30,619 --> 00:05:32,702 So, passwordResetExpires, 88 00:05:35,170 --> 00:05:37,460 which is where that date is stored, 89 00:05:37,460 --> 00:05:38,840 and now all we need to check 90 00:05:38,840 --> 00:05:41,470 if it is actually greater than right now. 91 00:05:41,470 --> 00:05:45,440 And so we know how to do that already with MongoDB, right? 92 00:05:45,440 --> 00:05:50,110 So, new object and then the greater operator 93 00:05:50,110 --> 00:05:53,737 and then what we want to compare it with is Date.now, 94 00:05:56,310 --> 00:05:59,410 and this will actually be a timestamp of right now, 95 00:05:59,410 --> 00:06:02,900 but behind the scenes, MongoDB will then convert everything 96 00:06:02,900 --> 00:06:05,170 to the same, and therefore be able 97 00:06:05,170 --> 00:06:06,520 to compare them accurately. 98 00:06:08,070 --> 00:06:10,440 And so with this we can, at the same time, 99 00:06:10,440 --> 00:06:14,120 find the user for the token and also check if the token 100 00:06:14,120 --> 00:06:16,370 has not yet expired. 101 00:06:16,370 --> 00:06:18,190 So, great. 102 00:06:18,190 --> 00:06:21,190 So, next up we want to, of course, send an error 103 00:06:21,190 --> 00:06:25,530 if there is no user, or basically, if the token has expired. 104 00:06:25,530 --> 00:06:27,230 But that's, in this case, the same, 105 00:06:27,230 --> 00:06:30,500 because if the token has expired, well then it will simply 106 00:06:30,500 --> 00:06:32,513 not return any user. 107 00:06:33,956 --> 00:06:37,730 And so all we need to do is to say, if no user, 108 00:06:38,970 --> 00:06:43,970 well then, as always, return next, that's not mext. 109 00:06:47,920 --> 00:06:51,910 So new AppError, and let's say 110 00:06:51,910 --> 00:06:56,793 Token is invalid or has expired. 111 00:06:59,850 --> 00:07:02,853 And then 400, so bad request. 112 00:07:04,140 --> 00:07:07,050 And so then, if there is no error, 113 00:07:07,050 --> 00:07:09,400 and if next is not called, 114 00:07:09,400 --> 00:07:12,160 well then let's actually set the password. 115 00:07:12,160 --> 00:07:15,550 So, we already got the user and now it's very simple: 116 00:07:15,550 --> 00:07:20,550 user.password is equal to req.body.password. 117 00:07:24,880 --> 00:07:28,140 And that's because we will of course, send the password 118 00:07:28,140 --> 00:07:31,713 and also passwordConfirm via the body. 119 00:07:33,551 --> 00:07:34,701 So let's duplicate that 120 00:07:37,870 --> 00:07:39,553 and passwordConfirm as well. 121 00:07:41,425 --> 00:07:44,630 And then also, let's basically delete the reset token 122 00:07:44,630 --> 00:07:45,733 and the expired. 123 00:07:46,800 --> 00:07:51,800 So passwordResetToken, so just like we did before, 124 00:07:52,040 --> 00:07:57,037 we set it to undefined, and now user.password expires 125 00:07:59,510 --> 00:08:01,160 equals to undefined. 126 00:08:01,160 --> 00:08:02,220 All right. 127 00:08:02,220 --> 00:08:04,350 And again, of course, we now need to save it, 128 00:08:04,350 --> 00:08:07,000 because this only modifies the document, 129 00:08:07,000 --> 00:08:08,410 it doesn't really update. 130 00:08:08,410 --> 00:08:09,973 So it doesn't really save it. 131 00:08:11,200 --> 00:08:15,503 So, await user.save. 132 00:08:17,500 --> 00:08:20,350 And in this case, we actually don't have to turn off 133 00:08:20,350 --> 00:08:24,340 the validators, because indeed we want to validate. 134 00:08:24,340 --> 00:08:27,620 For example, we want the validator to confirm 135 00:08:27,620 --> 00:08:31,440 if the password is equal to passwordConfirm. 136 00:08:31,440 --> 00:08:33,380 And so that validator automatically 137 00:08:33,380 --> 00:08:35,033 does all that work for us. 138 00:08:36,799 --> 00:08:39,390 Then the third step, what we're gonna do actually 139 00:08:39,390 --> 00:08:42,030 in the end, and so what we're gonna do next 140 00:08:42,030 --> 00:08:43,990 is to basically lock the user in. 141 00:08:43,990 --> 00:08:47,400 So in other words, send the JSON Web Token. 142 00:08:47,400 --> 00:08:51,930 And let's get that code from here, so this one. 143 00:08:51,930 --> 00:08:53,770 And again, we're already doing this here 144 00:08:53,770 --> 00:08:55,700 in three different places. 145 00:08:55,700 --> 00:08:59,280 So here in the login, also in signup, 146 00:08:59,280 --> 00:09:01,400 and now for the third time, down here. 147 00:09:01,400 --> 00:09:05,170 And so, sometime in the future, we will refactor that 148 00:09:05,170 --> 00:09:06,383 into its own function. 149 00:09:07,230 --> 00:09:09,673 But for now, we're good like this. 150 00:09:11,180 --> 00:09:14,743 And so, let's actually now go ahead and test this. 151 00:09:16,710 --> 00:09:19,020 So this reset token that we had before 152 00:09:19,020 --> 00:09:22,080 has already expired, and so we need to ask 153 00:09:22,080 --> 00:09:24,640 for a new one, basically. 154 00:09:24,640 --> 00:09:29,490 So let's come to Postman and hit our forget password route. 155 00:09:29,490 --> 00:09:32,120 Let's just reduce the clutter here 156 00:09:32,120 --> 00:09:36,350 and get rid of all of these open tabs 157 00:09:36,350 --> 00:09:37,500 that we no longer need. 158 00:09:38,910 --> 00:09:41,150 Actually here we're gonna need this test 159 00:09:43,480 --> 00:09:45,270 for this Reset Password, 160 00:09:45,270 --> 00:09:48,210 because remember, that this one actually gets back 161 00:09:48,210 --> 00:09:51,540 a JSON Web Token, and so we want to save that 162 00:09:51,540 --> 00:09:52,890 into the environment variable, 163 00:09:52,890 --> 00:09:54,830 just like we did with all the others. 164 00:09:54,830 --> 00:09:58,373 So I'm doing that now, just so that I don't forget it. 165 00:10:00,550 --> 00:10:04,100 All right, anyway, let's start with, basically, 166 00:10:04,100 --> 00:10:05,690 forgetting the password. 167 00:10:05,690 --> 00:10:08,620 So sending that request out, which again, 168 00:10:08,620 --> 00:10:10,750 takes some times because of sending the email, 169 00:10:10,750 --> 00:10:14,947 but here we go, and let's now go to our email, 170 00:10:16,880 --> 00:10:19,463 and so that just arrived a few seconds ago. 171 00:10:20,670 --> 00:10:24,890 So, it is this, of course, this token. 172 00:10:24,890 --> 00:10:29,890 So let's grab it, copy it and now back to Postman, 173 00:10:31,060 --> 00:10:34,303 we use it in the Reset Password, as the URL. 174 00:10:35,750 --> 00:10:37,253 Okay, make sense? 175 00:10:38,250 --> 00:10:41,603 So again, we're sending that token right in the URL. 176 00:10:43,600 --> 00:10:45,730 Then here, let's specify the body, 177 00:10:45,730 --> 00:10:49,453 because now, we need to actually specify our new password. 178 00:10:53,720 --> 00:10:57,843 So password and let's say newpass. 179 00:11:01,650 --> 00:11:03,050 And then... 180 00:11:05,950 --> 00:11:07,450 And here let's call it something else, 181 00:11:07,450 --> 00:11:10,263 because for now, I actually want to see an error. 182 00:11:11,480 --> 00:11:14,727 And of course, this is called passwordConfirm. 183 00:11:17,360 --> 00:11:20,393 So let's see what happens when we try to do this. 184 00:11:23,240 --> 00:11:27,080 Let's wait for it, and we get password is shorter 185 00:11:27,080 --> 00:11:29,640 than the minimum allowed length. 186 00:11:29,640 --> 00:11:34,480 Okay, so let's change that, 123, and here let's say 1234. 187 00:11:36,090 --> 00:11:37,740 So I want them to be different. 188 00:11:37,740 --> 00:11:40,630 But you see that the validation here worked just fine, 189 00:11:40,630 --> 00:11:43,273 even when updating the password with save. 190 00:11:45,610 --> 00:11:48,800 So, and now we get Passwords are not the same! 191 00:11:48,800 --> 00:11:50,960 So again, that's a validation error. 192 00:11:50,960 --> 00:11:53,430 And remember, actually, that this is the whole reason 193 00:11:53,430 --> 00:11:56,213 why we need to use save and not update. 194 00:11:57,206 --> 00:11:59,090 So before, for updating tours, 195 00:11:59,090 --> 00:12:03,220 we used to use findOneAndUpdate, but now, 196 00:12:03,220 --> 00:12:06,820 for everything related to passwords and to the user, 197 00:12:06,820 --> 00:12:10,110 we always use save, because we always want to run 198 00:12:10,110 --> 00:12:12,580 all the validators, and above all, 199 00:12:12,580 --> 00:12:14,450 the save middleware functions. 200 00:12:14,450 --> 00:12:18,293 So, for example, the ones where the passwords are encrypted. 201 00:12:20,400 --> 00:12:21,610 So let's end it now. 202 00:12:21,610 --> 00:12:25,030 Oh, I didn't actually correct it, sorry for that. 203 00:12:25,030 --> 00:12:28,230 And but now it should actually work. 204 00:12:28,230 --> 00:12:32,870 And indeed, we get success, and we get a new token. 205 00:12:32,870 --> 00:12:36,600 So great, let's see if this token is actually valid. 206 00:12:36,600 --> 00:12:40,973 So if we can, get all the tours using this brand new token. 207 00:12:43,870 --> 00:12:46,210 And here we go. 208 00:12:46,210 --> 00:12:51,000 So, our new token actually works, and now for this user, 209 00:12:51,000 --> 00:12:53,990 so for hello@jonas, these two properties 210 00:12:53,990 --> 00:12:56,190 should actually be gone. 211 00:12:56,190 --> 00:12:59,760 So the password expires and the token should be gone, 212 00:12:59,760 --> 00:13:03,550 since, well, since that's what we did in our code. 213 00:13:03,550 --> 00:13:06,760 And so, yeah, they are no longer here. 214 00:13:06,760 --> 00:13:10,210 Now all we need to do actually, is this missing step here, 215 00:13:10,210 --> 00:13:12,690 which is to update the passwordAt property 216 00:13:13,610 --> 00:13:14,773 for this current user. 217 00:13:15,680 --> 00:13:17,260 But that shouldn't be all too hard, 218 00:13:17,260 --> 00:13:20,690 and so let's quickly go back to the userModel, 219 00:13:20,690 --> 00:13:24,550 which is where we are gonna do that using middleware. 220 00:13:24,550 --> 00:13:26,800 And let's actually put all the middleware 221 00:13:26,800 --> 00:13:29,023 together here at the top. 222 00:13:32,241 --> 00:13:35,408 So, userSchema.pre and again dot save, 223 00:13:38,830 --> 00:13:42,763 and then a function with next. 224 00:13:44,850 --> 00:13:47,010 Again, this function here is gonna run 225 00:13:47,010 --> 00:13:50,890 right before a new document is actually saved. 226 00:13:50,890 --> 00:13:52,220 And so, it's the perfect place 227 00:13:52,220 --> 00:13:54,880 for actually specifying this property. 228 00:13:54,880 --> 00:13:57,480 And I could, of course, have done it in a controller 229 00:13:58,820 --> 00:14:01,133 right next to here to this code, for example. 230 00:14:02,310 --> 00:14:05,853 But I really want this to happen, kind of, automatically. 231 00:14:06,740 --> 00:14:08,700 So, kind of behind the scenes. 232 00:14:08,700 --> 00:14:11,350 Because later on, we will have another place 233 00:14:11,350 --> 00:14:15,290 where we update the password and then we would make sure 234 00:14:15,290 --> 00:14:17,410 that we're including the same code there. 235 00:14:17,410 --> 00:14:19,300 And like this, again, it happens, 236 00:14:19,300 --> 00:14:20,640 kind of, behind the scenes, 237 00:14:20,640 --> 00:14:23,810 without us having to worry about it at all. 238 00:14:23,810 --> 00:14:26,600 Now, when exactly do we actually want to set the 239 00:14:26,600 --> 00:14:30,630 passwordChangedAt property to right now? 240 00:14:30,630 --> 00:14:33,450 Well we only want it when we actually modified 241 00:14:33,450 --> 00:14:34,660 the password property. 242 00:14:34,660 --> 00:14:37,290 And I'm not sure if we used this trick before, 243 00:14:37,290 --> 00:14:39,660 but anyway, let's use it now. 244 00:14:39,660 --> 00:14:44,660 So if we have not modified, so if not this.isModified, 245 00:14:47,620 --> 00:14:49,100 so just like this, 246 00:14:49,100 --> 00:14:53,070 and then the name of the property, so password. 247 00:14:53,070 --> 00:14:56,380 So in that case, return right away 248 00:14:57,270 --> 00:14:59,360 and run the next middleware. 249 00:14:59,360 --> 00:15:02,823 Okay, not like this, but like this. 250 00:15:04,380 --> 00:15:07,770 So again, if we didn't modify the password property, 251 00:15:07,770 --> 00:15:08,770 well then of course, 252 00:15:08,770 --> 00:15:12,970 do not manipulate the passwordChangedAt. 253 00:15:12,970 --> 00:15:15,860 But what about creating new document? 254 00:15:15,860 --> 00:15:18,010 Well, when we create a new document, 255 00:15:18,010 --> 00:15:20,150 then we did actually modify the password, 256 00:15:20,150 --> 00:15:24,350 and then we would set the passwordChangedAt property, right? 257 00:15:24,350 --> 00:15:27,260 Well, in the current implementation we actually would. 258 00:15:27,260 --> 00:15:29,860 But there is something else that we can use here. 259 00:15:29,860 --> 00:15:32,950 So, basically, we want to exit this middleware function 260 00:15:32,950 --> 00:15:36,630 right away, if the password has not been modified 261 00:15:36,630 --> 00:15:40,274 or if the document is new, and so we can use 262 00:15:40,274 --> 00:15:41,633 the isNew property. 263 00:15:42,700 --> 00:15:46,210 And again, this is one of these very nice things 264 00:15:46,210 --> 00:15:48,290 that are learned by reading your documentation. 265 00:15:48,290 --> 00:15:52,010 And so, I cannot stress enough how important it is 266 00:15:52,010 --> 00:15:55,160 to really read the documentations when you need something 267 00:15:55,160 --> 00:15:56,870 that you cannot find anywhere. 268 00:15:56,870 --> 00:15:59,010 Because, there really is so much stuff in there 269 00:15:59,010 --> 00:16:02,983 that is completely impossible to teach in one course. 270 00:16:04,810 --> 00:16:08,500 Anyway, if the code passes this verification here, 271 00:16:08,500 --> 00:16:10,830 well, then let's very simply say, 272 00:16:10,830 --> 00:16:14,217 this.passwordChangedAt = Date.now. 273 00:16:18,660 --> 00:16:22,303 And then, we call next. 274 00:16:23,640 --> 00:16:26,300 Now, in theory, this should work just fine, 275 00:16:26,300 --> 00:16:27,590 but actually, in practice, 276 00:16:27,590 --> 00:16:30,160 sometimes a small problem happens. 277 00:16:30,160 --> 00:16:33,580 And that problem is that sometimes saving to the database 278 00:16:33,580 --> 00:16:37,440 is a bit slower than issuing the JSON Web Token, 279 00:16:37,440 --> 00:16:40,460 making it so that the changed password timestamp 280 00:16:40,460 --> 00:16:42,560 is sometimes set a bit after 281 00:16:42,560 --> 00:16:45,280 the JSON Web Token has been created. 282 00:16:45,280 --> 00:16:48,000 And so that will then make it so that the user 283 00:16:48,000 --> 00:16:51,120 will not be able to log in using the new token. 284 00:16:51,120 --> 00:16:54,570 Because, remember, the whole reason this timestamp here 285 00:16:54,570 --> 00:16:57,660 actually exists, is so that we can compare it 286 00:16:57,660 --> 00:17:01,200 with the timestamp on the JSON Web Token, right? 287 00:17:01,200 --> 00:17:04,353 So, just to remember, 288 00:17:05,930 --> 00:17:10,930 it is, well, so right here, where we check if the user 289 00:17:11,560 --> 00:17:15,170 has changed the password after the token was issued. 290 00:17:15,170 --> 00:17:18,920 And so, down here, where we then created this new token 291 00:17:18,920 --> 00:17:21,010 in reset password. 292 00:17:21,010 --> 00:17:24,170 So right here, remember, we create this new token, 293 00:17:24,170 --> 00:17:27,770 and so again, sometimes it happens that this token 294 00:17:27,770 --> 00:17:31,500 is created a bit before the changed password timestamp 295 00:17:31,500 --> 00:17:33,960 has actually been created. 296 00:17:33,960 --> 00:17:38,960 And so, we just need to fix that by subtracting one second. 297 00:17:39,610 --> 00:17:42,733 So, basically, a thousand milliseconds. 298 00:17:43,750 --> 00:17:47,670 And so that then will put the passwordChangedAt one second 299 00:17:47,670 --> 00:17:50,840 in the past, okay, which will then of course, 300 00:17:50,840 --> 00:17:54,500 not be 100% accurate, but that's not a problem at all, 301 00:17:54,500 --> 00:17:58,000 because one second here doesn't make any difference at all. 302 00:17:58,000 --> 00:18:01,213 It's a small hack, but again, it's no problem. 303 00:18:02,190 --> 00:18:06,190 So putting this passwordChanged one second in the past, 304 00:18:06,190 --> 00:18:08,920 will then ensure that the token is always created 305 00:18:08,920 --> 00:18:11,433 after the password has been changed. 306 00:18:13,290 --> 00:18:15,800 So, this works now, but as always, 307 00:18:15,800 --> 00:18:18,380 let's also quickly test it. 308 00:18:18,380 --> 00:18:21,060 Okay, so back to Postman. 309 00:18:21,060 --> 00:18:23,990 Let's do a new Reset Password, 310 00:18:23,990 --> 00:18:26,060 or actually, that's not what I wanted at all, 311 00:18:26,060 --> 00:18:28,400 but it's a great thing to see 312 00:18:28,400 --> 00:18:30,200 that the code is actually working. 313 00:18:30,200 --> 00:18:33,610 So, The token is invalid or has expired, 314 00:18:33,610 --> 00:18:35,999 and that's because, well, 10 minutes have passed 315 00:18:35,999 --> 00:18:38,640 since I actually created that token. 316 00:18:38,640 --> 00:18:41,240 And I think we hadn't yet tested this, 317 00:18:41,240 --> 00:18:45,043 and so it's great that it now accidentally, actually did it. 318 00:18:46,370 --> 00:18:50,160 So again, this comes, in case you're wondering 319 00:18:50,160 --> 00:18:51,493 what the hell happened, 320 00:18:53,840 --> 00:18:56,500 so that's of course this error message here. 321 00:18:56,500 --> 00:18:59,450 And so it means, that it didn't find any user 322 00:18:59,450 --> 00:19:03,216 which has this token or which has a token that is 323 00:19:03,216 --> 00:19:05,163 more than 10 minutes in the past. 324 00:19:06,600 --> 00:19:10,393 And so, indeed what I wanted to do, is forget password. 325 00:19:12,700 --> 00:19:14,073 So, let's wait for it. 326 00:19:18,000 --> 00:19:19,980 So 8.6 seconds, 327 00:19:19,980 --> 00:19:22,820 but that might be because of my internet connection. 328 00:19:22,820 --> 00:19:24,520 So if you run this on a server, 329 00:19:24,520 --> 00:19:26,373 it's probably gonna be a lot faster. 330 00:19:27,440 --> 00:19:31,900 So let's grab that here, back to Postman, and now 331 00:19:31,900 --> 00:19:36,740 we reset the password, again with this password, 332 00:19:36,740 --> 00:19:39,823 doesn't really matter if it's the same as the old one. 333 00:19:40,690 --> 00:19:43,580 And, so now we have our success here. 334 00:19:43,580 --> 00:19:45,193 And now back to Compass. 335 00:19:46,680 --> 00:19:51,210 Let's reload, and indeed, we get the passwordChangedAt. 336 00:19:51,210 --> 00:19:53,290 And so that is actually right now. 337 00:19:53,290 --> 00:19:57,220 And so, if we now tried to actually use this token, 338 00:19:57,220 --> 00:19:59,870 for example, to access this protected route, 339 00:19:59,870 --> 00:20:02,130 well then that should work because of that small, 340 00:20:02,130 --> 00:20:04,633 one second tag that we did. 341 00:20:06,090 --> 00:20:10,205 So, it did and so just like this, we actually now finished 342 00:20:10,205 --> 00:20:12,840 our Password Reset Functionality. 343 00:20:12,840 --> 00:20:16,400 So that was quite a bit of code, but of course, 344 00:20:16,400 --> 00:20:18,100 it's totally worth it. 345 00:20:18,100 --> 00:20:20,470 So, you should always offer this functionality 346 00:20:20,470 --> 00:20:22,874 in your web application, because otherwise, 347 00:20:22,874 --> 00:20:26,750 a user that forgets his password is completely screwed, 348 00:20:26,750 --> 00:20:29,140 they can non longer use your application, 349 00:20:29,140 --> 00:20:31,940 and so, that's of course a terrible practice. 350 00:20:31,940 --> 00:20:34,020 Anyway, this kind of finishes, already, 351 00:20:34,020 --> 00:20:38,520 the authentication and authorization part of this section. 352 00:20:38,520 --> 00:20:40,510 So again, it's quite complete 353 00:20:40,510 --> 00:20:43,250 and I had a lot of fun implementing this. 354 00:20:43,250 --> 00:20:46,341 So, this part for me is where web applications 355 00:20:46,341 --> 00:20:48,560 really start coming to life. 356 00:20:48,560 --> 00:20:51,280 I know that it's not really visible at this point, 357 00:20:51,280 --> 00:20:54,280 with all these, just tokens and copying tokens 358 00:20:54,280 --> 00:20:56,300 and paste them somewhere else. 359 00:20:56,300 --> 00:20:59,630 That's not the usual idea that we have of logging in, 360 00:20:59,630 --> 00:21:02,410 I know, but of course again, a bit later, 361 00:21:02,410 --> 00:21:05,430 when we finally start building the dynamic website, 362 00:21:05,430 --> 00:21:06,580 then we will of course, 363 00:21:06,580 --> 00:21:09,220 keep using this authentication that we just built 364 00:21:09,220 --> 00:21:13,350 and then it will also become visual on that dynamic website. 365 00:21:13,350 --> 00:21:16,833 Next up, we will implement functionality for updating 366 00:21:16,833 --> 00:21:19,620 the user and also deleting it, 367 00:21:19,620 --> 00:21:22,990 and after that, we will then also talk about security. 368 00:21:22,990 --> 00:21:25,800 So that's what's ahead for the rest of the section, 369 00:21:25,800 --> 00:21:28,323 so make sure not to miss that. 29612

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.