title
Learn The Mern Stack [9] - Backend JWT Auth
description
In this part we will add user registration and login with JWT (JSON Web Tokens) in Node/Express
Sponsor: DevMountain Bootcamp
https://goo.gl/6q0dEa
Original Series First Video:
https://www.youtube.com/watch?v=PBTYxXADG_k&list=PLillGF-RfqbbiTGgA77tGO426V3hRF9iE
Code:
https://github.com/bradtraversy/mern_shopping_list
💖 Become a Patron: Show support & get perks!
http://www.patreon.com/traversymedia
Website & Udemy Courses
http://www.traversymedia.com
Follow Traversy Media:
https://www.facebook.com/traversymedia
https://www.twitter.com/traversymedia
https://www.instagram.com/traversymedia
detail
{'title': 'Learn The Mern Stack [9] - Backend JWT Auth', 'heatmap': [{'end': 1151.047, 'start': 1083.934, 'weight': 0.744}, {'end': 1210.139, 'start': 1174.643, 'weight': 0.778}, {'end': 1473.336, 'start': 1434.827, 'weight': 0.814}, {'end': 1531.047, 'start': 1497.126, 'weight': 0.817}, {'end': 1885.774, 'start': 1819.36, 'weight': 0.728}, {'end': 2060.57, 'start': 1996.4, 'weight': 0.787}, {'end': 2148.39, 'start': 2114.522, 'weight': 0.701}, {'end': 2526.698, 'start': 2492.36, 'weight': 0.982}, {'end': 2645.608, 'start': 2556.374, 'weight': 0.785}, {'end': 2827, 'start': 2750.666, 'weight': 1}], 'summary': 'Tutorial series on the mern stack covers implementing json web tokens (jwt) for authentication, setting up user routes and server in express, user data handling and authentication, jwt configuration, generation, and user authentication, user and api authentication with jwt, and user authentication and token validation.', 'chapters': [{'end': 429.241, 'segs': [{'end': 100.706, 'src': 'embed', 'start': 24.019, 'weight': 0, 'content': [{'end': 27.963, 'text': "So I've had a bunch of requests over the past few months to continue my Learn.", 'start': 24.019, 'duration': 3.944}, {'end': 32.948, 'text': 'the Myrn Stack series on YouTube, where we use Node.js and Express on the back end,', 'start': 27.963, 'duration': 4.985}, {'end': 40.016, 'text': 'created a shopping list API and then created a front end with React and Redux and connected them together.', 'start': 32.948, 'duration': 7.068}, {'end': 42.118, 'text': 'We also used React Strap.', 'start': 40.696, 'duration': 1.422}, {'end': 47.6, 'text': 'which is a package that allows us to create bootstrap components as react components.', 'start': 42.518, 'duration': 5.082}, {'end': 52.343, 'text': 'So what I want to do in the next few videos is implement authentication.', 'start': 48.201, 'duration': 4.142}, {'end': 65.929, 'text': "That's. the main request that I've gotten is to add JWT or JSON Web tokens so that we can protect certain routes and then we can log in to get our register to get a token.", 'start': 52.383, 'duration': 13.546}, {'end': 70.611, 'text': "And then we'll send that token to the back end to access protected routes.", 'start': 66.089, 'duration': 4.522}, {'end': 72.33, 'text': "Okay, so that's what we're going to do.", 'start': 71.109, 'duration': 1.221}, {'end': 73.69, 'text': "It's quite a bit of code.", 'start': 72.55, 'duration': 1.14}, {'end': 77.652, 'text': "We're going to start off with the back end, implement it there, and then we'll move to React.", 'start': 73.71, 'duration': 3.942}, {'end': 80.494, 'text': "So it'll probably be three, maybe even four videos.", 'start': 77.672, 'duration': 2.822}, {'end': 89.638, 'text': 'Now, in this series, we used MLab, which is a service that offers remote MongoDB databases.', 'start': 81.614, 'duration': 8.024}, {'end': 93.201, 'text': 'and m lab is now owned by mongodb.', 'start': 90.058, 'duration': 3.143}, {'end': 100.706, 'text': "so what you want to do, if you're going to follow along, is create an account at mongodb.com and you want to use atlas,", 'start': 93.201, 'duration': 7.505}], 'summary': 'Continuing learn myrn stack series on youtube, implementing jwt for authentication in back end and react, using mlab now owned by mongodb.', 'duration': 76.687, 'max_score': 24.019, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM024019.jpg'}], 'start': 7.059, 'title': 'Implementing jwt for authentication', 'summary': 'Covers implementing json web tokens (jwt) for authentication in a web development series, including setting up mongodb atlas, connecting the front end and back end, and creating user models.', 'chapters': [{'end': 429.241, 'start': 7.059, 'title': 'Implementing jwt for authentication', 'summary': 'Covers implementing json web tokens (jwt) for authentication in a web development series, including setting up mongodb atlas, connecting the front end and back end, and creating user models.', 'duration': 422.182, 'highlights': ['Setting up MongoDB Atlas and connecting the front end and back end The speaker guides viewers on creating an account at mongodb.com, using MongoDB Atlas as the remote MongoDB service, and connecting the front end and back end to the database.', 'Creating user models and implementing JWT for authentication The speaker demonstrates creating a user model with fields for name, email, and password, and implementing JSON Web Tokens (JWT) for user authentication.', 'Utilizing React, Redux, and React Strap for front-end development The speaker mentions using React, Redux, and React Strap for front-end development, including updating React to use version two of create react app and installing necessary dependencies.']}], 'duration': 422.182, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM07059.jpg', 'highlights': ['Creating user models and implementing JWT for authentication The speaker demonstrates creating a user model with fields for name, email, and password, and implementing JSON Web Tokens (JWT) for user authentication.', 'Setting up MongoDB Atlas and connecting the front end and back end The speaker guides viewers on creating an account at mongodb.com, using MongoDB Atlas as the remote MongoDB service, and connecting the front end and back end to the database.', 'Utilizing React, Redux, and React Strap for front-end development The speaker mentions using React, Redux, and React Strap for front-end development, including updating React to use version two of create react app and installing necessary dependencies.']}, {'end': 728.501, 'segs': [{'end': 458.515, 'src': 'embed', 'start': 429.321, 'weight': 3, 'content': [{'end': 430.322, 'text': "And so let's save that.", 'start': 429.321, 'duration': 1.001}, {'end': 435.043, 'text': 'We now have our user model and we want to have some routes.', 'start': 430.422, 'duration': 4.621}, {'end': 438.204, 'text': 'OK, we want to route to be able to register a user.', 'start': 435.063, 'duration': 3.141}, {'end': 447.766, 'text': 'So in the routes folder, we have API as a folder and then our items that has all of our items routes inside API.', 'start': 438.744, 'duration': 9.022}, {'end': 452.347, 'text': "I'm also going to create a file called users dot JS.", 'start': 447.806, 'duration': 4.541}, {'end': 458.515, 'text': 'OK, and now in our server JS, we have to add that file as a route.', 'start': 453.45, 'duration': 5.065}], 'summary': 'Creating user model and routes in api folder.', 'duration': 29.194, 'max_score': 429.321, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM0429321.jpg'}, {'end': 512.357, 'src': 'embed', 'start': 482.435, 'weight': 5, 'content': [{'end': 485.839, 'text': "And then we'll copy that down and we want one for users.", 'start': 482.435, 'duration': 3.404}, {'end': 490.363, 'text': "So API slash users is going to go to that user's route file.", 'start': 485.919, 'duration': 4.444}, {'end': 494.581, 'text': "It's going to give me an error because there's nothing in that file.", 'start': 491.878, 'duration': 2.703}, {'end': 497.964, 'text': 'We need to actually implement the express router and all that stuff.', 'start': 494.681, 'duration': 3.283}, {'end': 501.588, 'text': "So let's go into users.js.", 'start': 499.145, 'duration': 2.443}, {'end': 505.812, 'text': "And I'll actually copy items.js real quick.", 'start': 502.869, 'duration': 2.943}, {'end': 508.715, 'text': 'Everything we have in items.js and the routes.', 'start': 506.472, 'duration': 2.243}, {'end': 512.357, 'text': 'and paste that in because we want to bring an express.', 'start': 509.735, 'duration': 2.622}], 'summary': 'Implementing the express router for api endpoints for users and items.', 'duration': 29.922, 'max_score': 482.435, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM0482435.jpg'}, {'end': 678.148, 'src': 'embed', 'start': 624.614, 'weight': 0, 'content': [{'end': 627.015, 'text': 'So we want to change that and that to post.', 'start': 624.614, 'duration': 2.401}, {'end': 631.597, 'text': "OK, and then let's do post to HTTP.", 'start': 628.075, 'duration': 3.522}, {'end': 639.133, 'text': 'localhost 5000 slash API slash users.', 'start': 634.15, 'duration': 4.983}, {'end': 643.195, 'text': 'And if we send that, we get a response back a 200 response.', 'start': 639.653, 'duration': 3.542}, {'end': 644.356, 'text': 'It just says register.', 'start': 643.215, 'duration': 1.141}, {'end': 647.237, 'text': 'OK, so we know that we can access that route.', 'start': 644.376, 'duration': 2.861}, {'end': 652.14, 'text': "So let's continue on here and let's actually register a user.", 'start': 648.458, 'duration': 3.682}, {'end': 655.882, 'text': "Obviously, we're going to have to send some data now express.", 'start': 652.22, 'duration': 3.662}, {'end': 658.504, 'text': 'The latest version of Express includes a body parser.', 'start': 655.942, 'duration': 2.562}, {'end': 662.785, 'text': 'Back when we did this, we had to – this is the server.js file.', 'start': 659.384, 'duration': 3.401}, {'end': 667.086, 'text': 'We had to install body parser separately and then add the middleware.', 'start': 663.165, 'duration': 3.921}, {'end': 669.306, 'text': "So what I'm going to do is just get rid of this.", 'start': 667.486, 'duration': 1.82}, {'end': 673.507, 'text': "And instead of this, we're going to do express.json.", 'start': 670.326, 'duration': 3.181}, {'end': 677.148, 'text': 'And then we can actually remove that package.', 'start': 674.687, 'duration': 2.461}, {'end': 678.148, 'text': 'We no longer need it.', 'start': 677.168, 'duration': 0.98}], 'summary': 'Configuring express to post data to localhost 5000/api/users and using express.json to eliminate body parser.', 'duration': 53.534, 'max_score': 624.614, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM0624614.jpg'}, {'end': 730.582, 'src': 'embed', 'start': 704.628, 'weight': 4, 'content': [{'end': 710.513, 'text': 'You can use the standard bcrypt, but I always run into issues with it, dependency issues and stuff, especially on Windows.', 'start': 704.628, 'duration': 5.885}, {'end': 714.876, 'text': "So especially if you're on Windows, I'd suggest using bcrypt.js.", 'start': 710.613, 'duration': 4.263}, {'end': 717.198, 'text': "So let's do run dev again.", 'start': 715.717, 'duration': 1.481}, {'end': 723.318, 'text': "Actually, you know what? We don't even need to do run dev because we're not dealing with React right now.", 'start': 719.136, 'duration': 4.182}, {'end': 728.501, 'text': "So I'm actually going to do run server, which will just run the back end.", 'start': 723.919, 'duration': 4.582}, {'end': 730.582, 'text': 'So npm run server.', 'start': 728.581, 'duration': 2.001}], 'summary': 'Recommend using bcrypt.js, run server instead of run dev on windows.', 'duration': 25.954, 'max_score': 704.628, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM0704628.jpg'}], 'start': 429.321, 'title': 'Setting up user routes and server in express', 'summary': 'Details the process of setting up user routes in express, including creating a route to register a new user, addressing a deprecation warning from mongoose, setting up an express server, testing user registration route using postman, updating to use express.json instead of body parser, and installing bcrypt.js for hashing passwords.', 'chapters': [{'end': 592.05, 'start': 429.321, 'title': 'Setting up user routes in express', 'summary': 'Details the process of setting up user routes in express, including creating a route to register a new user and addressing a deprecation warning from mongoose, with a focus on implementing the necessary files and methods.', 'duration': 162.729, 'highlights': ['The chapter details the process of setting up user routes in Express, including creating a route to register a new user and addressing a deprecation warning from Mongoose.', 'In the routes folder, a file called users.js is created to implement the express router and user model for user registration.', "The route for registering a new user is set to 'API/users' with a 'register' method, initially tested with a response of 'register'."]}, {'end': 728.501, 'start': 592.51, 'title': 'Express server setup and user registration', 'summary': 'Covers setting up an express server, testing user registration route using postman, updating to use express.json instead of body parser, and installing bcrypt.js for hashing passwords.', 'duration': 135.991, 'highlights': ['Setting up an Express server and testing user registration route using Postman The user demonstrates setting up an Express server and testing the user registration route using Postman, receiving a 200 response back upon successful registration.', 'Updating to use express.json instead of body parser The user updates the code to use express.json instead of body parser, eliminating the need for the body parser package and removing it from the dependencies.', 'Installing bcrypt.js for hashing passwords The user discusses the need to install bcrypt.js for hashing passwords while registering a user, especially recommending its use on Windows due to dependency issues with standard bcrypt.']}], 'duration': 299.18, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM0429321.jpg', 'highlights': ["The route for registering a new user is set to 'API/users' with a 'register' method, initially tested with a response of 'register'.", 'The user demonstrates setting up an Express server and testing the user registration route using Postman, receiving a 200 response back upon successful registration.', 'The user updates the code to use express.json instead of body parser, eliminating the need for the body parser package and removing it from the dependencies.', 'In the routes folder, a file called users.js is created to implement the express router and user model for user registration.', 'Installing bcrypt.js for hashing passwords The user discusses the need to install bcrypt.js for hashing passwords while registering a user, especially recommending its use on Windows due to dependency issues with standard bcrypt.', 'The chapter details the process of setting up user routes in Express, including creating a route to register a new user and addressing a deprecation warning from Mongoose.']}, {'end': 1272.421, 'segs': [{'end': 801.809, 'src': 'embed', 'start': 761.553, 'weight': 0, 'content': [{'end': 764.117, 'text': "And I'm just going to do some simple validation here.", 'start': 761.553, 'duration': 2.564}, {'end': 766.881, 'text': "So we'll do if.", 'start': 765.9, 'duration': 0.981}, {'end': 772.509, 'text': "Let's say if not name or not email or not.", 'start': 768.163, 'duration': 4.346}, {'end': 781.13, 'text': "password. then let's send a response.", 'start': 776.926, 'duration': 4.204}, {'end': 783.792, 'text': "so we're going to return res dot status.", 'start': 781.13, 'duration': 2.662}, {'end': 787.696, 'text': 'we want to send a status of 400, which is a bad request.', 'start': 783.792, 'duration': 3.904}, {'end': 801.809, 'text': "it means that the the user didn't send the correct info to get the correct response and then we'll just add on some json and let's just pass in a message and we'll say please enter all fields.", 'start': 787.696, 'duration': 14.113}], 'summary': 'Simple validation checks for name, email, and password, returning a 400 status with a message if fields are missing.', 'duration': 40.256, 'max_score': 761.553, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM0761553.jpg'}, {'end': 837.974, 'src': 'embed', 'start': 814.89, 'weight': 3, 'content': [{'end': 822.494, 'text': "okay, we're going, which is, we're using mongoose and we're going to use the find one method and we want to find by email.", 'start': 814.89, 'duration': 7.604}, {'end': 823.735, 'text': 'so we pass in an object.', 'start': 822.494, 'duration': 1.241}, {'end': 825.576, 'text': 'we want to say we want to look for the email.', 'start': 823.735, 'duration': 1.841}, {'end': 830.539, 'text': "that's equal to the email variable and since these are the same, i can simply just do that.", 'start': 825.576, 'duration': 4.963}, {'end': 835.072, 'text': "OK, and then that's going to give us a promise back.", 'start': 832.33, 'duration': 2.742}, {'end': 835.853, 'text': "So we'll do that.", 'start': 835.092, 'duration': 0.761}, {'end': 837.974, 'text': 'Then if you want to use a sink away, you can.', 'start': 835.953, 'duration': 2.021}], 'summary': 'Using mongoose, find one method to search by email. returns a promise.', 'duration': 23.084, 'max_score': 814.89, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM0814890.jpg'}, {'end': 1036.484, 'src': 'embed', 'start': 1005.637, 'weight': 1, 'content': [{'end': 1008.579, 'text': 'And this bcrypt hash is going to take in a couple of things.', 'start': 1005.637, 'duration': 2.942}, {'end': 1013.062, 'text': 'It takes in the plain text password, which is going to be this new user dot password.', 'start': 1008.619, 'duration': 4.443}, {'end': 1017.266, 'text': "So we'll pass in new user dot password.", 'start': 1013.663, 'duration': 3.603}, {'end': 1019.827, 'text': 'Then it takes in the salt that was generated.', 'start': 1017.786, 'duration': 2.041}, {'end': 1024.211, 'text': "So we'll pass that in, and then a callback with a possible error and the hash.", 'start': 1019.928, 'duration': 4.283}, {'end': 1031.32, 'text': 'OK Now once we get the hash we will actually check for the error first.', 'start': 1026.817, 'duration': 4.503}, {'end': 1036.484, 'text': "So if there's an error we'll just go ahead and stop it and throw the error.", 'start': 1032.162, 'duration': 4.322}], 'summary': 'Bcrypt hash takes plain text password and salt, then checks for error.', 'duration': 30.847, 'max_score': 1005.637, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM01005637.jpg'}, {'end': 1151.047, 'src': 'heatmap', 'start': 1083.934, 'weight': 0.744, 'content': [{'end': 1087.797, 'text': 'going to have an object with a user object.', 'start': 1083.934, 'duration': 3.863}, {'end': 1089.678, 'text': "we'll have the token as well later on.", 'start': 1087.797, 'duration': 1.881}, {'end': 1095.241, 'text': "but for now we'll just have the user and i don't want to send the entire user back with the password.", 'start': 1089.678, 'duration': 5.563}, {'end': 1096.162, 'text': 'so we want the name.', 'start': 1095.241, 'duration': 0.921}, {'end': 1104.868, 'text': "um, actually, let's do, let's do the id as well, so user.id.", 'start': 1096.162, 'duration': 8.706}, {'end': 1108.21, 'text': "username. and then let's do email.", 'start': 1104.868, 'duration': 3.342}, {'end': 1113.384, 'text': "OK, so it'll send that stuff back.", 'start': 1111.783, 'duration': 1.601}, {'end': 1114.364, 'text': 'And we should be good.', 'start': 1113.584, 'duration': 0.78}, {'end': 1115.344, 'text': "So we'll save that.", 'start': 1114.404, 'duration': 0.94}, {'end': 1117.805, 'text': "And let's try and register a user.", 'start': 1116.144, 'duration': 1.661}, {'end': 1120.546, 'text': "So we'll go back to Postman.", 'start': 1117.905, 'duration': 2.641}, {'end': 1123.067, 'text': 'And we already have our request here.', 'start': 1121.426, 'duration': 1.641}, {'end': 1125.808, 'text': 'But we need to add some data to register with.', 'start': 1123.127, 'duration': 2.681}, {'end': 1130.229, 'text': 'Because right now, if I try it, we get, please enter all fields.', 'start': 1125.828, 'duration': 4.401}, {'end': 1135.591, 'text': 'So in order to send data, we need to go to our headers and set a content type.', 'start': 1130.909, 'duration': 4.682}, {'end': 1151.047, 'text': "uh, let's set a content, type of application slash json and then in the body we'll choose raw json and let's put in our double quotes here.", 'start': 1137.581, 'duration': 13.466}], 'summary': 'Developing a user object with specific fields and setting content type for registration.', 'duration': 67.113, 'max_score': 1083.934, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM01083934.jpg'}, {'end': 1247.142, 'src': 'heatmap', 'start': 1174.643, 'weight': 2, 'content': [{'end': 1177.021, 'text': "I'm going to do 1, 2, 3, 4, 5, 6.", 'start': 1174.643, 'duration': 2.378}, {'end': 1178.144, 'text': 'But it should get hashed.', 'start': 1177.024, 'duration': 1.12}, {'end': 1179.505, 'text': "So let's send.", 'start': 1178.624, 'duration': 0.881}, {'end': 1184.867, 'text': 'And then we get a response back, 200 response with the user ID, name, and email.', 'start': 1180.345, 'duration': 4.522}, {'end': 1193.59, 'text': "And if we head over to Atlas and I reload, we should have a user's collection, which we do.", 'start': 1185.207, 'duration': 8.383}, {'end': 1197.851, 'text': "And if we look in user's collection, we have the user we just registered.", 'start': 1193.79, 'duration': 4.061}, {'end': 1199.152, 'text': 'And take a look at the password.', 'start': 1197.871, 'duration': 1.281}, {'end': 1200.312, 'text': "It's completely hashed.", 'start': 1199.212, 'duration': 1.1}, {'end': 1201.677, 'text': 'All right.', 'start': 1201.397, 'duration': 0.28}, {'end': 1204.298, 'text': 'So we now have the ability to register a user.', 'start': 1201.717, 'duration': 2.581}, {'end': 1210.139, 'text': 'So now we want to do is is implement tokens.', 'start': 1205.358, 'duration': 4.781}, {'end': 1218.341, 'text': 'OK, I want to make it so that when we register, we get a token just like when we log in so that we can immediately log in from our front end.', 'start': 1210.159, 'duration': 8.182}, {'end': 1222.642, 'text': 'So if we go to JWT dot IO.', 'start': 1218.881, 'duration': 3.761}, {'end': 1232.329, 'text': 'This tells us a little bit about what JSON Web tokens are, and I actually have a video on JWT where I just kind of explain it a little bit.', 'start': 1224.562, 'duration': 7.767}, {'end': 1237.894, 'text': "I give you a basic example, a node without a database, but basically it's it's it's looks like this.", 'start': 1232.369, 'duration': 5.525}, {'end': 1247.142, 'text': "So it's easy to send back and forth and it has three parts to it, has the header which has the algorithm and then the token type.", 'start': 1238.714, 'duration': 8.428}], 'summary': 'Implemented user registration with hashed passwords and started implementing tokens for immediate login from the front end.', 'duration': 45.425, 'max_score': 1174.643, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM01174643.jpg'}], 'start': 728.581, 'title': 'User data handling and authentication', 'summary': 'Discusses data validation and user validation, including the usage of destructuring for name, email, and password, implementing validation for bad requests, and checking for existing users. it also covers user registration, password hashing using bcrypt, and the implementation of json web tokens for authentication.', 'chapters': [{'end': 835.853, 'start': 728.581, 'title': 'User data validation and existing user check', 'summary': 'Discusses data validation in the users route, including the usage of destructuring to extract name, email, and password, and implementing validation to send a status of 400 for bad requests. it also covers checking for existing users using the find one method with mongoose.', 'duration': 107.272, 'highlights': ['The chapter covers data validation in the users route, including the usage of destructuring to extract name, email, and password, and implementing validation to send a status of 400 for bad requests.', 'It also discusses checking for existing users using the find one method with Mongoose.']}, {'end': 1272.421, 'start': 835.953, 'title': 'User registration and token implementation', 'summary': 'Covers the process of registering a new user, including the hashing of the password using bcrypt, and the implementation of json web tokens for user authentication, enabling immediate login from the front end, and also provides a brief introduction to json web tokens.', 'duration': 436.468, 'highlights': ['The process of registering a new user, including the hashing of the password using bcrypt The transcript explains the steps involved in creating a new user, including the use of bcrypt to hash the password for secure storage in the database.', 'Implementation of JSON Web Tokens for user authentication, enabling immediate login from the front end The chapter discusses the implementation of JSON Web Tokens to provide user authentication and enable immediate login from the front end, enhancing user experience and security.', 'Introduction to JSON Web Tokens, including its structure and components The transcript briefly introduces JSON Web Tokens, explaining its structure with three parts: header, payload, and signature, and mentions the inclusion of data such as issued at, expiration, user ID, and name.']}], 'duration': 543.84, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM0728581.jpg', 'highlights': ['The chapter covers data validation in the users route, including the usage of destructuring to extract name, email, and password, and implementing validation to send a status of 400 for bad requests.', 'The process of registering a new user, including the hashing of the password using bcrypt.', 'Implementation of JSON Web Tokens for user authentication, enabling immediate login from the front end.', 'It also discusses checking for existing users using the find one method with Mongoose.', 'Introduction to JSON Web Tokens, including its structure and components.']}, {'end': 1954.754, 'segs': [{'end': 1385.007, 'src': 'embed', 'start': 1353.694, 'weight': 4, 'content': [{'end': 1356.756, 'text': "So I'm going to install a package here called config.", 'start': 1353.694, 'duration': 3.062}, {'end': 1359.899, 'text': 'so that we can handle this a little differently.', 'start': 1358.038, 'duration': 1.861}, {'end': 1362.76, 'text': "And we'll go ahead and run the server.", 'start': 1360.899, 'duration': 1.861}, {'end': 1370.622, 'text': "Instead of having this keys.js, I'm going to have a JSON file inside config called default.", 'start': 1363.24, 'duration': 7.382}, {'end': 1373.003, 'text': 'So default.json.', 'start': 1371.042, 'duration': 1.961}, {'end': 1385.007, 'text': "And in this default.json, we're going to have a JSON object with any secrets, any API keys, connection strings, stuff like that.", 'start': 1374.844, 'duration': 10.163}], 'summary': "Installing 'config' package to manage secrets and api keys in a json file.", 'duration': 31.313, 'max_score': 1353.694, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM01353694.jpg'}, {'end': 1473.336, 'src': 'heatmap', 'start': 1434.827, 'weight': 0.814, 'content': [{'end': 1441.27, 'text': 'We put it right here in this DB variable we use that keys file and then we just use that Mongo you are I value.', 'start': 1434.827, 'duration': 6.443}, {'end': 1444.712, 'text': "So, instead of doing that, I'm just going to bring in config.", 'start': 1441.69, 'duration': 3.022}, {'end': 1465.849, 'text': 'Okay, and now I can simply do instead of this I can do config.get and then pass in Mongo URI.', 'start': 1451.015, 'duration': 14.834}, {'end': 1473.336, 'text': 'Oh, I forgot the quote.', 'start': 1471.915, 'duration': 1.421}], 'summary': 'Utilized config.get to retrieve the mongo uri from the keys file.', 'duration': 38.509, 'max_score': 1434.827, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM01434827.jpg'}, {'end': 1531.047, 'src': 'heatmap', 'start': 1497.126, 'weight': 0.817, 'content': [{'end': 1501.209, 'text': 'And then we also want Jason Web tokens.', 'start': 1497.126, 'duration': 4.083}, {'end': 1502.67, 'text': "So let's bring that in.", 'start': 1501.549, 'duration': 1.121}, {'end': 1511.936, 'text': "We'll say const JWT equals require Jason Web token.", 'start': 1502.87, 'duration': 9.066}, {'end': 1516.037, 'text': 'right now down where we did the register.', 'start': 1513.755, 'duration': 2.282}, {'end': 1520.28, 'text': "we're going to want to change this up a little bit.", 'start': 1516.037, 'duration': 4.243}, {'end': 1531.047, 'text': "so this is all the same the hashing we're going to save the user and then in the response is where we want to also create the token.", 'start': 1520.28, 'duration': 10.767}], 'summary': 'Integrating jason web tokens for user authentication and response token creation.', 'duration': 33.921, 'max_score': 1497.126, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM01497126.jpg'}, {'end': 1615.771, 'src': 'embed', 'start': 1557.931, 'weight': 0, 'content': [{'end': 1569.211, 'text': "So that way, when we send a token from React or from Postman, wherever it's coming from, The user ID is in there so that it knows which user it is.", 'start': 1557.931, 'duration': 11.28}, {'end': 1573.131, 'text': 'Okay Otherwise, any token could access anything.', 'start': 1569.231, 'duration': 3.9}, {'end': 1577.352, 'text': 'So you want to make sure that you send that ID and you verify it to do certain things.', 'start': 1573.251, 'duration': 4.101}, {'end': 1579.012, 'text': "Okay So that's the payload.", 'start': 1577.372, 'duration': 1.64}, {'end': 1582.713, 'text': 'And you could add more stuff if you wanted the name and stuff like that.', 'start': 1579.072, 'duration': 3.641}, {'end': 1583.553, 'text': 'All right.', 'start': 1583.333, 'duration': 0.22}, {'end': 1585.874, 'text': 'The next parameter is going to be the secret.', 'start': 1583.673, 'duration': 2.201}, {'end': 1588.154, 'text': "So let's do config dot get.", 'start': 1585.974, 'duration': 2.18}, {'end': 1593.315, 'text': 'And we want to get the JWT secret value.', 'start': 1589.094, 'duration': 4.221}, {'end': 1596.641, 'text': 'now, this next one is optional.', 'start': 1594.46, 'duration': 2.181}, {'end': 1598.882, 'text': "it's if you want it to expire, and i do.", 'start': 1596.641, 'duration': 2.241}, {'end': 1604.285, 'text': "i'm going to say expires in, and i'm going to set it to 3600.", 'start': 1598.882, 'duration': 5.403}, {'end': 1609.147, 'text': 'all right.', 'start': 1604.285, 'duration': 4.862}, {'end': 1612.889, 'text': 'so what i did here is set it to an hour, so 3600 seconds.', 'start': 1609.147, 'duration': 3.742}, {'end': 1615.771, 'text': "so this token will only last for an hour, and it's up to you.", 'start': 1612.889, 'duration': 2.882}], 'summary': 'When sending a token, include user id for verification and set expiration time to 3600 seconds.', 'duration': 57.84, 'max_score': 1557.931, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM01557931.jpg'}, {'end': 1713.451, 'src': 'embed', 'start': 1667.92, 'weight': 1, 'content': [{'end': 1677.123, 'text': "Now, in addition to the user, I want to send the token, so I'm just going to simply add token, which is the same as doing token equals token.", 'start': 1667.92, 'duration': 9.203}, {'end': 1681.941, 'text': 'OK. so once we register, not only will it give us the user back,', 'start': 1678.3, 'duration': 3.641}, {'end': 1688.063, 'text': "it should give us a token so that we can then authenticate with private routes which we haven't set up yet.", 'start': 1681.941, 'duration': 6.122}, {'end': 1694.764, 'text': 'OK, in many past tutorials and like in my Mernstack course, we used Passport JS.', 'start': 1688.863, 'duration': 5.901}, {'end': 1698.646, 'text': 'We use that middleware to create private routes and all that.', 'start': 1695.405, 'duration': 3.241}, {'end': 1703.887, 'text': "But I'm actually going to show you how we can write just very simple custom middleware to handle that.", 'start': 1698.726, 'duration': 5.161}, {'end': 1707.37, 'text': "But before we do anything else, let's test this out.", 'start': 1705.049, 'duration': 2.321}, {'end': 1709.35, 'text': "So let's make sure that this is saved.", 'start': 1707.47, 'duration': 1.88}, {'end': 1713.451, 'text': "And then let's go back and let's try to register a new user.", 'start': 1709.89, 'duration': 3.561}], 'summary': 'Adding token for user authentication and creating custom middleware for private routes.', 'duration': 45.531, 'max_score': 1667.92, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM01667920.jpg'}, {'end': 1885.774, 'src': 'heatmap', 'start': 1819.36, 'weight': 0.728, 'content': [{'end': 1826.448, 'text': "OK, so I'm going to just copy everything from the user's route and paste that in here.", 'start': 1819.36, 'duration': 7.088}, {'end': 1831.093, 'text': 'So because we want to bring in most of this, all of this stuff, actually.', 'start': 1827.128, 'duration': 3.965}, {'end': 1833.956, 'text': "And then let's see.", 'start': 1833.095, 'duration': 0.861}, {'end': 1835.558, 'text': 'We want to bring in our user model.', 'start': 1833.996, 'duration': 1.562}, {'end': 1841.104, 'text': "And then let's have a route that is a post request to API slash auth.", 'start': 1836.138, 'duration': 4.966}, {'end': 1847.162, 'text': 'So this is going to authenticate the user.', 'start': 1842.139, 'duration': 5.023}, {'end': 1849.403, 'text': "It's going to be public.", 'start': 1848.463, 'duration': 0.94}, {'end': 1856.388, 'text': "Obviously, it's going to be public because this is the way that we actually get the token so that we can then send it along to private routes.", 'start': 1850.244, 'duration': 6.144}, {'end': 1865.767, 'text': "And then we're gonna just grab the email and the password no need for the name Validation we'll just check for email and password.", 'start': 1857.642, 'duration': 8.125}, {'end': 1866.908, 'text': 'So same thing.', 'start': 1866.188, 'duration': 0.72}, {'end': 1869.65, 'text': "Please enter all fields So we'll go down.", 'start': 1867.088, 'duration': 2.562}, {'end': 1873.132, 'text': "We'll check for the user by the email.", 'start': 1869.69, 'duration': 3.442}, {'end': 1876.875, 'text': "Now, if there's not a user, that's when we want to send back an error.", 'start': 1873.132, 'duration': 3.743}, {'end': 1885.774, 'text': "So we're gonna say if not, user return 400 and we're gonna say user does not exist.", 'start': 1876.875, 'duration': 8.899}], 'summary': 'Creating a public post route for user authentication with email and password validation.', 'duration': 66.414, 'max_score': 1819.36, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM01819360.jpg'}], 'start': 1272.421, 'title': 'Jwt configuration, generation, and user authentication', 'summary': 'Covers configuring jwt and secrets handling, emphasizing using environment variables, and explains jwt token generation with an expiration time of 3600 seconds and user authentication using custom middleware.', 'chapters': [{'end': 1583.553, 'start': 1272.421, 'title': 'Configuring jwt and secrets handling', 'summary': 'Covers the process of configuring jwt usage, handling secrets using a package called config, and the importance of handling sensitive information securely, emphasizing the use of environment variables instead of hardcoding them.', 'duration': 311.132, 'highlights': ['The chapter covers the process of configuring JWT usage, handling secrets using a package called config, and the importance of handling sensitive information securely, emphasizing the use of environment variables instead of hardcoding them. This section provides an overview of the topics discussed in the transcript, including configuring JWT usage, handling secrets using a package called config, and the importance of handling sensitive information securely, emphasizing the use of environment variables instead of hardcoding them.', 'The need for secure handling of sensitive information is emphasized, with a recommendation to use environment variables to store secrets and avoid exposing them in repositories. The importance of securely handling sensitive information is highlighted, with a recommendation to use environment variables to store secrets and avoid exposing them in repositories to maintain security and confidentiality.', "The process of using the package 'config' to handle sensitive information is explained, demonstrating the creation of a 'default.json' file to store secrets, including API keys and connection strings. The transcript details the process of using the package 'config' to handle sensitive information, demonstrating the creation of a 'default.json' file to store secrets, including API keys and connection strings, providing a more secure method of managing sensitive data.", "The method of accessing configuration values using 'config.get' is presented, showcasing a cleaner approach to retrieving configuration values and enhancing code readability. The method of accessing configuration values using 'config.get' is presented, showcasing a cleaner and more organized approach to retrieving configuration values, thereby enhancing code readability and maintainability.", 'The utilization of JWT to create a token with a specific payload, including the user ID, is demonstrated, emphasizing the importance of including essential information within the token for proper verification and access control. The utilization of JWT to create a token with a specific payload, including the user ID, is demonstrated, emphasizing the importance of including essential information within the token for proper verification and access control, ensuring secure authorization and access management.']}, {'end': 1954.754, 'start': 1583.673, 'title': 'Jwt token generation and user authentication', 'summary': 'Explains how to generate a jwt token with an expiration time of 3600 seconds, and then authenticate users to obtain a token for accessing private routes, utilizing custom middleware for authentication.', 'duration': 371.081, 'highlights': ['Generate JWT token with 3600 seconds expiration time The chapter explains setting the JWT token expiration time to 3600 seconds, allowing the token to last for an hour.', 'Custom middleware for user authentication Demonstrates creating custom middleware for user authentication instead of using Passport JS, providing an alternative approach for handling private routes.', 'User registration and token retrieval Illustrates the process of registering a user and obtaining a token, enabling authentication for private routes, demonstrating the practical application of JWT tokens.']}], 'duration': 682.333, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM01272421.jpg', 'highlights': ['Generate JWT token with 3600 seconds expiration time', 'Custom middleware for user authentication', 'User registration and token retrieval', 'The utilization of JWT to create a token with a specific payload, including the user ID, is demonstrated, emphasizing the importance of including essential information within the token for proper verification and access control.', "The process of using the package 'config' to handle sensitive information is explained, demonstrating the creation of a 'default.json' file to store secrets, including API keys and connection strings."]}, {'end': 2402.874, 'segs': [{'end': 1991.056, 'src': 'embed', 'start': 1954.754, 'weight': 0, 'content': [{'end': 1955.935, 'text': 'so does it match or not?', 'start': 1954.754, 'duration': 1.181}, {'end': 1962.697, 'text': "OK now, if it doesn't match, then obviously they're not going to.", 'start': 1957.714, 'duration': 4.983}, {'end': 1964.077, 'text': "we don't want them to authenticate.", 'start': 1962.697, 'duration': 1.38}, {'end': 1974.663, 'text': "So we'll say if not match, then let's return a response status of 400 because it's a bad request and it's not it's not a correct login.", 'start': 1964.097, 'duration': 10.566}, {'end': 1978.905, 'text': "And we'll say Jason and let's do.", 'start': 1975.443, 'duration': 3.462}, {'end': 1983.067, 'text': "We'll say message.", 'start': 1978.925, 'duration': 4.142}, {'end': 1989.035, 'text': 'Invalid credentials.', 'start': 1985.888, 'duration': 3.147}, {'end': 1991.056, 'text': 'All right.', 'start': 1990.756, 'duration': 0.3}], 'summary': "If credentials don't match, return 400 status with 'invalid credentials' message.", 'duration': 36.302, 'max_score': 1954.754, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM01954754.jpg'}, {'end': 2060.57, 'src': 'heatmap', 'start': 1996.4, 'weight': 0.787, 'content': [{'end': 2002.083, 'text': 'So in that case, we want to send the token and the user just like we did in our registration.', 'start': 1996.4, 'duration': 5.683}, {'end': 2004.265, 'text': "So I'm just going to grab from users JS.", 'start': 2002.143, 'duration': 2.122}, {'end': 2010.869, 'text': 'I want to grab this whole JWT sign with the response inside the callback.', 'start': 2005.586, 'duration': 5.283}, {'end': 2012.511, 'text': 'So it ends right here.', 'start': 2011.37, 'duration': 1.141}, {'end': 2017.314, 'text': "So I'm just going to grab that chunk and I'm going to put that right here.", 'start': 2012.551, 'duration': 4.763}, {'end': 2023.565, 'text': "OK, so again, we're signing the token, we're passing in the user ID as a payload.", 'start': 2018.28, 'duration': 5.285}, {'end': 2024.986, 'text': 'We fetch the user here.', 'start': 2023.725, 'duration': 1.261}, {'end': 2028.529, 'text': "So we're passing the ID and then we get our secrets.", 'start': 2025.146, 'duration': 3.383}, {'end': 2030.772, 'text': "It's going to expire in an hour.", 'start': 2029.33, 'duration': 1.442}, {'end': 2035.756, 'text': 'We have our callback and then we send a response with a token and a user.', 'start': 2031.172, 'duration': 4.584}, {'end': 2037.518, 'text': 'OK, so that should do it.', 'start': 2036.497, 'duration': 1.021}, {'end': 2038.078, 'text': "Let's save.", 'start': 2037.538, 'duration': 0.54}, {'end': 2043.341, 'text': "and let's go back to postman and now let's make a.", 'start': 2039.139, 'duration': 4.202}, {'end': 2045.242, 'text': "actually, i'll just i'll use this one.", 'start': 2043.341, 'duration': 1.901}, {'end': 2052.406, 'text': 'so, instead of a post request to api users, we want to do api slash off and as far as the body goes,', 'start': 2045.242, 'duration': 7.164}, {'end': 2056.428, 'text': "we don't need a name because we're not creating a user, we're just validating.", 'start': 2052.406, 'duration': 4.022}, {'end': 2060.57, 'text': "but let's do a user that doesn't exist, like brad1 at gmail.", 'start': 2056.428, 'duration': 4.142}], 'summary': 'Signing and sending jwt token for user authentication, with an expiration of one hour.', 'duration': 64.17, 'max_score': 1996.4, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM01996400.jpg'}, {'end': 2043.341, 'src': 'embed', 'start': 2018.28, 'weight': 1, 'content': [{'end': 2023.565, 'text': "OK, so again, we're signing the token, we're passing in the user ID as a payload.", 'start': 2018.28, 'duration': 5.285}, {'end': 2024.986, 'text': 'We fetch the user here.', 'start': 2023.725, 'duration': 1.261}, {'end': 2028.529, 'text': "So we're passing the ID and then we get our secrets.", 'start': 2025.146, 'duration': 3.383}, {'end': 2030.772, 'text': "It's going to expire in an hour.", 'start': 2029.33, 'duration': 1.442}, {'end': 2035.756, 'text': 'We have our callback and then we send a response with a token and a user.', 'start': 2031.172, 'duration': 4.584}, {'end': 2037.518, 'text': 'OK, so that should do it.', 'start': 2036.497, 'duration': 1.021}, {'end': 2038.078, 'text': "Let's save.", 'start': 2037.538, 'duration': 0.54}, {'end': 2043.341, 'text': "and let's go back to postman and now let's make a.", 'start': 2039.139, 'duration': 4.202}], 'summary': 'Signing token with user id as payload, expiring in an hour, and sending response with token and user.', 'duration': 25.061, 'max_score': 2018.28, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM02018280.jpg'}, {'end': 2148.39, 'src': 'heatmap', 'start': 2072.056, 'weight': 2, 'content': [{'end': 2074.719, 'text': 'So we need to actually go to server.js.', 'start': 2072.056, 'duration': 2.663}, {'end': 2085.126, 'text': 'And just like we did with the other two routes right here, we need to bring in API auth and API auth.', 'start': 2074.759, 'duration': 10.367}, {'end': 2093.001, 'text': "okay. so let's try that again and we get a response that says user does not exist.", 'start': 2086.579, 'duration': 6.422}, {'end': 2097.503, 'text': "now if we do brad at gmail, which does exist, and we do a password, that's wrong.", 'start': 2093.001, 'duration': 4.502}, {'end': 2099.924, 'text': 'we get invalid credentials.', 'start': 2097.503, 'duration': 2.421}, {'end': 2107.767, 'text': "so let's try with the password that's right and send and we get a token and we get the user.", 'start': 2099.924, 'duration': 7.843}, {'end': 2113.409, 'text': 'so same response whether we register or whether we authenticate if we log in.', 'start': 2107.767, 'duration': 5.642}, {'end': 2116.643, 'text': 'So this makes it pretty easy on the front end.', 'start': 2114.522, 'duration': 2.121}, {'end': 2117.883, 'text': 'All right.', 'start': 2117.523, 'duration': 0.36}, {'end': 2128.167, 'text': 'Now, the last part of this is to create the middleware so that we can have private routes that are only accessed if we send along this token.', 'start': 2117.963, 'duration': 10.204}, {'end': 2134.309, 'text': "OK, so what we'll do here is create our own middleware.", 'start': 2129.007, 'duration': 5.302}, {'end': 2136.489, 'text': "So let's see.", 'start': 2134.409, 'duration': 2.08}, {'end': 2137.67, 'text': 'We want to be in the route.', 'start': 2136.509, 'duration': 1.161}, {'end': 2139.15, 'text': "I'm just going to close all this stuff.", 'start': 2137.71, 'duration': 1.44}, {'end': 2143.927, 'text': "And in the route, let's create a folder called middleware.", 'start': 2139.85, 'duration': 4.077}, {'end': 2148.39, 'text': "And inside here, we'll create a file called off.js.", 'start': 2144.508, 'duration': 3.882}], 'summary': 'Implementing authentication and creating middleware for private routes in server.js.', 'duration': 56.111, 'max_score': 2072.056, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM02072056.jpg'}, {'end': 2191.254, 'src': 'embed', 'start': 2159.619, 'weight': 4, 'content': [{'end': 2170.427, 'text': "OK, and then we'll bring in Jason Webb token, we'll set that to JWT.", 'start': 2159.619, 'duration': 10.808}, {'end': 2178.265, 'text': "OK, so we're just going to create a middleware function and just call it off.", 'start': 2173.081, 'duration': 5.184}, {'end': 2185.11, 'text': 'And when you have a middleware function, you want to pass in three things, the request, the response and next.', 'start': 2179.366, 'duration': 5.744}, {'end': 2191.254, 'text': "OK, when you're done with whatever this piece of middleware does, you want to call next to move on to the next middleware.", 'start': 2185.13, 'duration': 6.124}], 'summary': 'Creating a middleware function with jwt token for request, response, and next.', 'duration': 31.635, 'max_score': 2159.619, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM02159619.jpg'}, {'end': 2341.238, 'src': 'embed', 'start': 2305.371, 'weight': 5, 'content': [{'end': 2313.593, 'text': "And the way that we do that is I'm going to create a variable called decoded and set that to JWT dot verify.", 'start': 2305.371, 'duration': 8.222}, {'end': 2316.654, 'text': 'And we want to pass in that token.', 'start': 2313.613, 'duration': 3.041}, {'end': 2328.016, 'text': 'And this also takes in that JWT secret so we can say config.get and JWT secret.', 'start': 2318.203, 'duration': 9.813}, {'end': 2330.19, 'text': 'All right.', 'start': 2329.85, 'duration': 0.34}, {'end': 2336.935, 'text': 'Now we want to take the user from the token, because remember, we set the ID.', 'start': 2330.37, 'duration': 6.565}, {'end': 2341.238, 'text': "It's sending the user ID and we want to put that into request dot user.", 'start': 2337.095, 'duration': 4.143}], 'summary': "Creating a variable 'decoded' to verify jwt token and extract user id into request.user.", 'duration': 35.867, 'max_score': 2305.371, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM02305371.jpg'}, {'end': 2402.874, 'src': 'embed', 'start': 2371.454, 'weight': 7, 'content': [{'end': 2380.938, 'text': "Now, actually, what I want to do is wrap this in a try catch, because if the token isn't valid, then we obviously we don't want to do that.", 'start': 2371.454, 'duration': 9.484}, {'end': 2383.018, 'text': 'We want to send back an error response.', 'start': 2380.978, 'duration': 2.04}, {'end': 2385.079, 'text': "So let's just do try.", 'start': 2383.518, 'duration': 1.561}, {'end': 2402.874, 'text': "Let's say try catch and we'll have our exception and then we'll just take this and let's grab actually this too and let's move this up.", 'start': 2387.869, 'duration': 15.005}], 'summary': 'Wrapping the code in a try-catch block to handle invalid tokens and send back an error response.', 'duration': 31.42, 'max_score': 2371.454, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM02371454.jpg'}], 'start': 1954.754, 'title': 'User and api authentication with jwt', 'summary': 'Covers user authentication, token generation, and expiration, api authentication, middleware creation, and token verification with jwt, ensuring secure access and user validation for private routes.', 'chapters': [{'end': 2043.341, 'start': 1954.754, 'title': 'User authentication and token generation', 'summary': 'Explains the process of user authentication, returning a response status of 400 for invalid credentials, and generating a jwt token upon successful login, with the token expiring in an hour.', 'duration': 88.587, 'highlights': ['The chapter explains returning a response status of 400 for invalid credentials, ensuring a secure authentication process.', 'It demonstrates the process of generating a JWT token upon successful login, with the token expiring in an hour.', 'The chapter outlines the steps to be taken if the credentials do not match, ensuring a comprehensive authentication process.']}, {'end': 2191.254, 'start': 2043.341, 'title': 'Api authentication and middleware creation', 'summary': 'Discusses the process of api authentication, including validating users, generating tokens, and creating middleware for private routes, as well as the use of jwt for authentication.', 'duration': 147.913, 'highlights': ['The process of API authentication, including user validation and token generation, is demonstrated, with examples of error messages for non-existent and invalid user credentials.', 'Creation of middleware for private routes is explained, involving the use of JWT and the implementation of a middleware function with parameters for request, response, and next.']}, {'end': 2402.874, 'start': 2191.937, 'title': 'Token verification function', 'summary': 'Explains the process of token verification in a middleware function, checking for the presence of a token in the header, and then verifying it using jwt, with the specific handling of unauthorized requests and successful user addition to the request object.', 'duration': 210.937, 'highlights': ["The function checks for the presence of a token in the request header and sends a 401 status along with a message if no token is found. It sets up a check for the token in the request header and sends a 401 status along with a message 'no token authorization denied' if the token is not present.", "It verifies the token using JWT and sets the user ID from the token into the request object. After verifying the token using JWT, it extracts the user ID from the token and stores it in the request object, ensuring the user's presence in the request.", 'The function is wrapped in a try-catch block to handle invalid tokens and send an error response. The function is enclosed in a try-catch block to handle the case of an invalid token, ensuring the appropriate error response is sent.']}], 'duration': 448.12, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM01954754.jpg', 'highlights': ['The chapter outlines the steps to be taken if the credentials do not match, ensuring a comprehensive authentication process.', 'It demonstrates the process of generating a JWT token upon successful login, with the token expiring in an hour.', 'Covers user authentication, token generation, and expiration, api authentication, middleware creation, and token verification with jwt, ensuring secure access and user validation for private routes.', 'The process of API authentication, including user validation and token generation, is demonstrated, with examples of error messages for non-existent and invalid user credentials.', 'Creation of middleware for private routes is explained, involving the use of JWT and the implementation of a middleware function with parameters for request, response, and next.', "It verifies the token using JWT and sets the user ID from the token into the request object. After verifying the token using JWT, it extracts the user ID from the token and stores it in the request object, ensuring the user's presence in the request.", 'The chapter explains returning a response status of 400 for invalid credentials, ensuring a secure authentication process.', 'The function is wrapped in a try-catch block to handle invalid tokens and send an error response. The function is enclosed in a try-catch block to handle the case of an invalid token, ensuring the appropriate error response is sent.']}, {'end': 2936.79, 'segs': [{'end': 2472.584, 'src': 'embed', 'start': 2441.975, 'weight': 0, 'content': [{'end': 2450.824, 'text': 'So now whenever we want a private route we can simply add this piece of middleware as the second parameter in the end point.', 'start': 2441.975, 'duration': 8.849}, {'end': 2456.87, 'text': "So for instance let's go to Let's go to our items routes.", 'start': 2450.985, 'duration': 5.885}, {'end': 2459.092, 'text': 'So eight routes, API items.', 'start': 2457.13, 'duration': 1.962}, {'end': 2465.598, 'text': 'And what I want is the the post here to create a new item and the delete.', 'start': 2459.693, 'duration': 5.905}, {'end': 2469.761, 'text': 'I want the I want to have them to have to be authenticated.', 'start': 2465.758, 'duration': 4.003}, {'end': 2472.584, 'text': "So what we'll do is bring in our middleware.", 'start': 2470.422, 'duration': 2.162}], 'summary': 'Adding middleware to private routes for item creation and deletion, requiring authentication.', 'duration': 30.609, 'max_score': 2441.975, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM02441975.jpg'}, {'end': 2526.698, 'src': 'heatmap', 'start': 2492.36, 'weight': 0.982, 'content': [{'end': 2499.422, 'text': 'So outside of routes and then into middleware and then in and then we want the auth file.', 'start': 2492.36, 'duration': 7.062}, {'end': 2508.485, 'text': 'OK, and then all we have to do to protect this this post request right here to create a new item is simply add auth.', 'start': 2500.122, 'duration': 8.363}, {'end': 2514.104, 'text': 'as a second parameter just like that case for same thing for delete.', 'start': 2509.378, 'duration': 4.726}, {'end': 2515.465, 'text': 'We just want to add off.', 'start': 2514.264, 'duration': 1.201}, {'end': 2518.208, 'text': 'So now those routes should be protected.', 'start': 2516.206, 'duration': 2.002}, {'end': 2526.698, 'text': "So if I go back to postman and I try to add an item let's make a post request and let's do HTTP.", 'start': 2518.368, 'duration': 8.33}], 'summary': 'Adding authentication to routes for protecting post and delete requests.', 'duration': 34.338, 'max_score': 2492.36, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM02492360.jpg'}, {'end': 2601.575, 'src': 'embed', 'start': 2571.647, 'weight': 1, 'content': [{'end': 2577.129, 'text': "So let's go back here and this is the route to actually log in and get the token.", 'start': 2571.647, 'duration': 5.482}, {'end': 2577.829, 'text': 'Sorry about that.', 'start': 2577.189, 'duration': 0.64}, {'end': 2581.21, 'text': "And I'll press send and then we have our token.", 'start': 2578.83, 'duration': 2.38}, {'end': 2582.351, 'text': "So I'm going to copy this.", 'start': 2581.271, 'duration': 1.08}, {'end': 2588.593, 'text': "Go back to our post request to add the item and we're going to add in the headers.", 'start': 2584.011, 'duration': 4.582}, {'end': 2593.949, 'text': 'a value here of X dash off dash token.', 'start': 2589.525, 'duration': 4.424}, {'end': 2601.575, 'text': "So we would do this within reactor angular view whatever it is we're using on the front end and then we want to set the value to the token.", 'start': 2594.449, 'duration': 7.126}], 'summary': 'Demonstrating the process of obtaining and using a token for authentication in a post request.', 'duration': 29.928, 'max_score': 2571.647, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM02571647.jpg'}, {'end': 2669.737, 'src': 'heatmap', 'start': 2556.374, 'weight': 4, 'content': [{'end': 2566.945, 'text': "So I'm going to send this and check out what we get a 401 unauthorized response and it says no token authorized denied authorization denied.", 'start': 2556.374, 'duration': 10.571}, {'end': 2571.127, 'text': 'So in order to do this, we need to have the token.', 'start': 2567.686, 'duration': 3.441}, {'end': 2577.129, 'text': "So let's go back here and this is the route to actually log in and get the token.", 'start': 2571.647, 'duration': 5.482}, {'end': 2577.829, 'text': 'Sorry about that.', 'start': 2577.189, 'duration': 0.64}, {'end': 2581.21, 'text': "And I'll press send and then we have our token.", 'start': 2578.83, 'duration': 2.38}, {'end': 2582.351, 'text': "So I'm going to copy this.", 'start': 2581.271, 'duration': 1.08}, {'end': 2588.593, 'text': "Go back to our post request to add the item and we're going to add in the headers.", 'start': 2584.011, 'duration': 4.582}, {'end': 2593.949, 'text': 'a value here of X dash off dash token.', 'start': 2589.525, 'duration': 4.424}, {'end': 2601.575, 'text': "So we would do this within reactor angular view whatever it is we're using on the front end and then we want to set the value to the token.", 'start': 2594.449, 'duration': 7.126}, {'end': 2604.958, 'text': "OK so now I'm going to send and it gets added.", 'start': 2601.595, 'duration': 3.363}, {'end': 2613.359, 'text': 'OK And just to make sure if we go to Atlas and we go to items We should have stake.', 'start': 2604.978, 'duration': 8.381}, {'end': 2613.879, 'text': 'And there it is.', 'start': 2613.379, 'duration': 0.5}, {'end': 2622.363, 'text': 'Now, the last thing we want to do is we want to create a route inside of JS, because in this route,', 'start': 2614.119, 'duration': 8.244}, {'end': 2628.647, 'text': "what it's going to do is check for the current user, get the current user's data by using the token.", 'start': 2622.363, 'duration': 6.284}, {'end': 2633.229, 'text': 'The reason we want to do this is because JWT authentication is stateless.', 'start': 2629.107, 'duration': 4.122}, {'end': 2641.005, 'text': "It's not like using sessions where you have authentication data stored in memory or whatever on the server.", 'start': 2633.669, 'duration': 7.336}, {'end': 2645.608, 'text': 'you just send your token, it decodes it and then it sends you the response.', 'start': 2641.005, 'duration': 4.603}, {'end': 2651.993, 'text': "So we need a way to constantly validate the user that's logged in in our front end.", 'start': 2645.688, 'duration': 6.305}, {'end': 2655.695, 'text': "So we need a route that's just going to take the token and then return the user data.", 'start': 2652.033, 'duration': 3.662}, {'end': 2660.278, 'text': 'So in auth JS, I want to bring in our auth middleware.', 'start': 2656.496, 'duration': 3.782}, {'end': 2664.621, 'text': "So I'm going to say const auth, set that to require.", 'start': 2660.418, 'duration': 4.203}, {'end': 2669.177, 'text': "and let's see where are we.", 'start': 2667.795, 'duration': 1.382}, {'end': 2669.737, 'text': "so we're in.", 'start': 2669.177, 'duration': 0.56}], 'summary': 'The process involves obtaining a token, adding it to a post request, and creating a route to validate user data through jwt authentication.', 'duration': 47.374, 'max_score': 2556.374, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM02556374.jpg'}, {'end': 2827, 'src': 'heatmap', 'start': 2742.558, 'weight': 3, 'content': [{'end': 2750.126, 'text': "And we're going to take our user model we're going to call find by ID and we just need to pass in the ID.", 'start': 2742.558, 'duration': 7.568}, {'end': 2765.36, 'text': "Now we can get that by doing request user dot ID and I don't want to return the password so I can simply do dot select and then just do pass in here.", 'start': 2750.666, 'duration': 14.694}, {'end': 2768.601, 'text': 'um, hyphen password.', 'start': 2766.52, 'duration': 2.081}, {'end': 2776.166, 'text': "Okay So that will just disregard the password and then this will give us a response and we want to, it'll give us the user.", 'start': 2768.621, 'duration': 7.545}, {'end': 2777.527, 'text': "Um, I'm sorry.", 'start': 2776.186, 'duration': 1.341}, {'end': 2783.691, 'text': 'It will give us a promise with the user and then we want to just send that user.', 'start': 2777.547, 'duration': 6.144}, {'end': 2785.972, 'text': 'Okay And it will minus the password.', 'start': 2783.711, 'duration': 2.261}, {'end': 2787.573, 'text': "And that's it.", 'start': 2787.093, 'duration': 0.48}, {'end': 2790.635, 'text': 'So that will validate the user with the token.', 'start': 2787.653, 'duration': 2.982}, {'end': 2793.076, 'text': "So let's try this out in Postman.", 'start': 2790.835, 'duration': 2.241}, {'end': 2798.819, 'text': "So I'm going to take this token.", 'start': 2793.096, 'duration': 5.723}, {'end': 2802.44, 'text': 'So this is the token that belongs to the Brad Traverse user.', 'start': 2798.919, 'duration': 3.521}, {'end': 2807.603, 'text': "So I'm going to take that and I'm going to make a get request to HTTP.", 'start': 2802.46, 'duration': 5.143}, {'end': 2827, 'text': 'localhost 5000 slash api slash auth slash user and I want to attach a headers value of x dash auth, dash token and pass that token,', 'start': 2809.392, 'duration': 17.608}], 'summary': 'User model finds and returns user without password for validation with token.', 'duration': 26.043, 'max_score': 2742.558, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM02742558.jpg'}, {'end': 2873.268, 'src': 'embed', 'start': 2835.285, 'weight': 2, 'content': [{'end': 2841.089, 'text': 'Now if I authenticate with a different user I think we have.', 'start': 2835.285, 'duration': 5.804}, {'end': 2844.091, 'text': 'Do we register any other users.', 'start': 2841.909, 'duration': 2.182}, {'end': 2846.272, 'text': "Let's register a user real quick.", 'start': 2844.751, 'duration': 1.521}, {'end': 2858.76, 'text': "So if we go post request to users and let's just do like john at gmail send, please enter all fields.", 'start': 2846.352, 'duration': 12.408}, {'end': 2860.382, 'text': "that's right, because this is registration.", 'start': 2858.76, 'duration': 1.622}, {'end': 2861.344, 'text': 'we need to add a name.', 'start': 2860.382, 'duration': 0.962}, {'end': 2873.268, 'text': "OK, so we'll send that and now this token should reveal that this is the John Doe user.", 'start': 2866.664, 'duration': 6.604}], 'summary': "Register a user 'john doe' with all fields for authentication.", 'duration': 37.983, 'max_score': 2835.285, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM02835285.jpg'}], 'start': 2405.174, 'title': 'User authentication and token validation', 'summary': 'Covers creating middleware for authentication, adding item after providing token, implementing jwt authentication for fetching user data, creating protected route, user authentication, token validation, retrieving user data and validating user tokens, and registering and authenticating users.', 'chapters': [{'end': 2622.363, 'start': 2405.174, 'title': 'Creating middleware for authentication', 'summary': 'Explains the process of creating middleware for authentication, demonstrating how to protect routes by adding the middleware as a second parameter, resulting in a 401 unauthorized response when a token is not provided, and successfully adding an item after providing the token.', 'duration': 217.189, 'highlights': ['Demonstrates adding the created middleware as a second parameter to protect routes, resulting in a 401 unauthorized response when a token is not provided. 401 unauthorized response', 'Successfully adds an item after providing the token. successfully adding an item']}, {'end': 2739.797, 'start': 2622.363, 'title': 'Jwt authentication for user data', 'summary': 'Discusses the implementation of jwt authentication for fetching user data, emphasizing the constant validation of the logged-in user in the front end and the creation of a protected route to return user data.', 'duration': 117.434, 'highlights': ['The JWT authentication is stateless, requiring a route to constantly validate the user in the front end.', 'Implementation of a protected route (API/off/user) to fetch user data using JWT authentication.', 'Emphasizing the need for constant validation of the logged-in user in the front end.']}, {'end': 2936.79, 'start': 2742.558, 'title': 'User authentication and token validation', 'summary': 'Covers user authentication and token validation using the user model, showing how to retrieve user data and validate user tokens in postman, as well as the process of registering and authenticating users, including the association of tokens with specific user identities.', 'duration': 194.232, 'highlights': ['The chapter covers user authentication and token validation using the user model, showing how to retrieve user data and validate user tokens in Postman, as well as the process of registering and authenticating users, including the association of tokens with specific user identities.', "By calling 'find by ID' and passing the user ID, the system retrieves the user data and excludes the password, providing a response with the user details.", 'Demonstrates the use of tokens in Postman to authenticate and retrieve user data, showcasing the association of tokens with specific user identities.', 'The process of registering and authenticating users is detailed, including the generation and association of tokens with specific user identities.']}], 'duration': 531.616, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/USaB1adUHM0/pics/USaB1adUHM02405174.jpg', 'highlights': ['Demonstrates adding the created middleware as a second parameter to protect routes, resulting in a 401 unauthorized response when a token is not provided. 401 unauthorized response', 'Successfully adds an item after providing the token. successfully adding an item', 'The chapter covers user authentication and token validation using the user model, showing how to retrieve user data and validate user tokens in Postman, as well as the process of registering and authenticating users, including the association of tokens with specific user identities.', "By calling 'find by ID' and passing the user ID, the system retrieves the user data and excludes the password, providing a response with the user details.", 'Demonstrates the use of tokens in Postman to authenticate and retrieve user data, showcasing the association of tokens with specific user identities.', 'The process of registering and authenticating users is detailed, including the generation and association of tokens with specific user identities.', 'The JWT authentication is stateless, requiring a route to constantly validate the user in the front end.', 'Implementation of a protected route (API/off/user) to fetch user data using JWT authentication.', 'Emphasizing the need for constant validation of the logged-in user in the front end.']}], 'highlights': ["The process of using the package 'config' to handle sensitive information is explained, demonstrating the creation of a 'default.json' file to store secrets, including API keys and connection strings.", 'The chapter outlines the steps to be taken if the credentials do not match, ensuring a comprehensive authentication process.', 'The process of registering and authenticating users is detailed, including the generation and association of tokens with specific user identities.', 'The chapter covers user authentication, token generation, and expiration, api authentication, middleware creation, and token verification with jwt, ensuring secure access and user validation for private routes.', 'The process of API authentication, including user validation and token generation, is demonstrated, with examples of error messages for non-existent and invalid user credentials.']}