title
React Protected Routes | Role-Based Authorization | React Router v6

description
Web Dev Roadmap for Beginners (Free!): https://bit.ly/DaveGrayWebDevRoadmap React Protected Routes allows you to make part of your React app exclusive to authorized users. Role-Based Authorization allows different levels of access based upon the assigned user roles. This tutorial utilizes React Router v6. ⭐ Become a full-stack web dev with Zero To Mastery Courses: - Advanced React & Redux: https://bit.ly/AdvReactDev - Jr to Senior Web Dev Roadmap: https://bit.ly/WebDevRoadmap-JrtoSr - Master FAANG Coding Interviews: https://bit.ly/FAANGInterview 🚩 Subscribe ➜ https://bit.ly/3nGHmNn 🚀 React JS for Beginners full course - 9 hours: https://youtu.be/RVFAyFWO4go 🔗 Source Code: https://github.com/gitdagray/react_protected_routes 📬 Course Updates ➜ https://courses.davegray.codes/ React Protected Routes | Role-Based Authorization | React Router v6 (00:00) Intro (00:53) Welcome and Startup (01:27) Install React Router v6 (02:17) Update index.js with RRv6 (03:38) Basic Routing Setup (07:41) useAuth hook (10:06) RequireAuth component v1 (14:38) Manage browser history (18:50) Testing with backend authentication (21:00) RequireAuth component v2 (24:26) Applying Role-Based Routing (26:35) Object lookup for roles (28:15) Testing role-based routes (29:37) Last note on the Unauthorized component ☕ Buy Me A Coffee: https://www.buymeacoffee.com/davegray 🔗 React Router Version 6 in 20 minutes: https://youtu.be/XBRLVRjZ3CQ 🔗 React User Login and Authentication with Axios: https://youtu.be/X3qyxo_UTR4 🔗 React Register Form with Validation, Axios and a11y: https://youtu.be/brcHK3P6ChQ 🔗 Node JS Full Course (with source code) for building the backend REST API that will receive your form submissions: https://youtu.be/f2EqECiTBL8 🔗 FontAwesome for React: https://fontawesome.com/v5.15/how-to-use/on-the-web/using-with/react 🔗 RegExr for Regular Expressions: https://regexr.com/ 📚 Accessible Form References: WebAIM.org - Advanced Forms: https://webaim.org/techniques/forms/advanced WebAIM.org - Form Validation: https://webaim.org/techniques/formvalidation/ MDN - Aria Attributes: aria-invalid: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-invalid_attribute aria-describedby: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-describedby aria-live: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-live aria-label: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label 🔗 ES7 React JS Snippets Extension for VS Code: https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets 🔗 React Dev Tools Extension for Chrome: https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi 📚 References: ReactJS Official site: https://reactjs.org/ React Wikipedia: https://en.wikipedia.org/wiki/React_(JavaScript_library) React Jobs: https://www.ziprecruiter.com/candidate/search?search=react&location= ✅ Follow Me: Github: https://github.com/gitdagray Twitter: https://twitter.com/yesdavidgray LinkedIn: https://www.linkedin.com/in/davidagray/ Blog: https://yesdavidgray.com Reddit: https://www.reddit.com/user/DaveOnEleven Was this tutorial about creating protected routes and role-based user authorization in React with React Router v6 helpful? If so, please share. Let me know your thoughts in the comments. #react #protected #routes

detail
{'title': 'React Protected Routes | Role-Based Authorization | React Router v6', 'heatmap': [{'end': 277.061, 'start': 197.598, 'weight': 1}, {'end': 610.51, 'start': 552.482, 'weight': 0.72}, {'end': 812.714, 'start': 773.65, 'weight': 0.753}, {'end': 908.089, 'start': 862.93, 'weight': 0.811}, {'end': 1115.384, 'start': 1032.599, 'weight': 0.726}], 'summary': 'Tutorial series on react router v6 covers creating protected routes, implementing global authentication, user authentication, authorization, route protection, and role-based user permissions for different roles, aiming to target intermediate react developers and streamline the process.', 'chapters': [{'end': 38.411, 'segs': [{'end': 45.538, 'src': 'embed', 'start': 18.678, 'weight': 0, 'content': [{'end': 23.78, 'text': "But after that, he'll attempt to access the admin page, and he'll be unauthorized to do so.", 'start': 18.678, 'duration': 5.102}, {'end': 27.182, 'text': 'He can go to the lounge where admins and editors hang out.', 'start': 24.06, 'duration': 3.122}, {'end': 29.263, 'text': "And now we'll look at Jane.", 'start': 28.082, 'duration': 1.181}, {'end': 38.411, 'text': "when jane logs in, she's an admin, but she'll try to access the editor's page, which is only for editors, so she'll be unauthorized for that.", 'start': 30.083, 'duration': 8.328}, {'end': 45.538, 'text': 'however, she can access the admin page and she can also access the lounge where admins and editors hang out.', 'start': 38.411, 'duration': 7.127}], 'summary': 'Unauthorized access: user unauthorized to access admin and editor pages.', 'duration': 26.86, 'max_score': 18.678, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY18678.jpg'}], 'start': 0.089, 'title': 'Role-based protected routes in react router v6', 'summary': 'Introduces react router v6, demonstrating the creation of protected routes with role-based user permissions. it showcases user restrictions for kevin, dave, and jane based on their varying roles.', 'chapters': [{'end': 38.411, 'start': 0.089, 'title': 'React router v6: role-based protected routes', 'summary': 'Introduces react router v6, showcasing the ability to create protected routes with role-based user permissions. it illustrates how different users with varying roles, such as kevin, dave, and jane, are restricted from accessing certain pages based on their permissions.', 'duration': 38.322, 'highlights': ["Kevin can log in and see the home page, but he can't access anything else.", "Dave, an editor, can view the editor's page but will be unauthorized to access the admin page.", "Jane, an admin, will be unauthorized to access the editor's page, which is only for editors."]}], 'duration': 38.322, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY89.jpg', 'highlights': ["Dave, an editor, can view the editor's page but will be unauthorized to access the admin page.", "Jane, an admin, will be unauthorized to access the editor's page, which is only for editors.", "Kevin can log in and see the home page, but he can't access anything else."]}, {'end': 456.15, 'segs': [{'end': 104.769, 'src': 'embed', 'start': 38.411, 'weight': 0, 'content': [{'end': 45.538, 'text': 'however, she can access the admin page and she can also access the lounge where admins and editors hang out.', 'start': 38.411, 'duration': 7.127}, {'end': 47.8, 'text': "let's look at the react code that makes all of this work.", 'start': 45.538, 'duration': 2.262}, {'end': 54.09, 'text': 'Hello and welcome.', 'start': 53.089, 'duration': 1.001}, {'end': 54.891, 'text': "Hi, I'm Dave.", 'start': 54.15, 'duration': 0.741}, {'end': 59.255, 'text': "Today we're going to create protected routes with React Router version 6.", 'start': 55.091, 'duration': 4.164}, {'end': 62.878, 'text': 'These protected routes will also have role-based user permissions.', 'start': 59.255, 'duration': 3.623}, {'end': 66.822, 'text': 'This is more of an intermediate level React tutorial than it is beginner.', 'start': 63.338, 'duration': 3.484}, {'end': 73.568, 'text': 'Ideally, you will have already completed my ReactJS for Beginners course or a similar course for getting started with React.', 'start': 67.342, 'duration': 6.226}, {'end': 81.255, 'text': "And I have separate tutorials for the login and register forms you'll see today, as well as the node backend we'll use for authentication.", 'start': 74.088, 'duration': 7.167}, {'end': 87.081, 'text': "I put links to all of those in the description, and I'll share a link to the source code for this lesson too.", 'start': 81.475, 'duration': 5.606}, {'end': 95.006, 'text': "Now you can see I've got Visual Studio Code open to full screen here, And we're looking at the dependencies in the package JSON.", 'start': 87.661, 'duration': 7.345}, {'end': 104.769, 'text': "Now, while most of these dependencies already existed for the register or the login page, one we'll be adding today is React Router DOM version 6.", 'start': 95.386, 'duration': 9.383}], 'summary': 'Creating protected routes with react router v6, including role-based user permissions for an intermediate level tutorial.', 'duration': 66.358, 'max_score': 38.411, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY38411.jpg'}, {'end': 158.391, 'src': 'embed', 'start': 129.4, 'weight': 2, 'content': [{'end': 131.801, 'text': "And then after it's installed, come back to the tutorial.", 'start': 129.4, 'duration': 2.401}, {'end': 137.463, 'text': "I'm going to close the terminal window, and we're going to look at the index.js now.", 'start': 132.501, 'duration': 4.962}, {'end': 141.404, 'text': "In the index.js, we're going to import several things from React Router.", 'start': 137.823, 'duration': 3.581}, {'end': 153.109, 'text': "So we'll start with browser router, and then we also need routes, and then the singular route, all from react-router-dom.", 'start': 141.444, 'duration': 11.665}, {'end': 158.391, 'text': "And once we've imported those, we're going to start with the browser router.", 'start': 153.889, 'duration': 4.502}], 'summary': 'The tutorial covers importing components from react router, including browserrouter and routes from react-router-dom.', 'duration': 28.991, 'max_score': 129.4, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY129400.jpg'}, {'end': 281.845, 'src': 'heatmap', 'start': 197.598, 'weight': 6, 'content': [{'end': 204.063, 'text': 'So the only way those will match up with the root is to go ahead and have the slash and the asterisk instead of just the slash.', 'start': 197.598, 'duration': 6.465}, {'end': 207.325, 'text': "And then let's go ahead and put the element attribute.", 'start': 204.683, 'duration': 2.642}, {'end': 211.868, 'text': 'And inside this element attribute is where we put our app component.', 'start': 207.565, 'duration': 4.303}, {'end': 218.176, 'text': "And once we've done that, we just need to close the route component and we're finished with the index.js file.", 'start': 212.368, 'duration': 5.808}, {'end': 221.72, 'text': "Now let's look at the app component in the app.js file.", 'start': 218.456, 'duration': 3.264}, {'end': 225.524, 'text': 'And you can see I have imported a lot of components already.', 'start': 221.94, 'duration': 3.584}, {'end': 235.092, 'text': "Most of these will just be to navigate between to show the different user-based permissions, but overall we'll look at a few of those in more detail.", 'start': 225.625, 'duration': 9.467}, {'end': 244.238, 'text': 'now, inside the functional app component itself, with the return, you can see, we left this where we had the login tutorial, with the main element,', 'start': 235.092, 'duration': 9.146}, {'end': 247.24, 'text': 'class name of app applied and the login component.', 'start': 244.238, 'duration': 3.002}, {'end': 252.583, 'text': "inside we're going to replace all of that with a layout component.", 'start': 247.24, 'duration': 5.343}, {'end': 254.404, 'text': "so let's look at this layout component.", 'start': 252.583, 'duration': 1.821}, {'end': 257.565, 'text': "We're importing outlet from React Router DOM.", 'start': 254.884, 'duration': 2.681}, {'end': 265.152, 'text': "And then inside the functional component itself, we're returning what mostly looks like what we had inside of the app.js.", 'start': 258.087, 'duration': 7.065}, {'end': 269.595, 'text': 'We have that main element, class name set equal to app.', 'start': 265.772, 'duration': 3.823}, {'end': 272.618, 'text': 'But now we have the outlet component inside.', 'start': 270.016, 'duration': 2.602}, {'end': 277.061, 'text': 'The outlet component represents all the children of the layout component.', 'start': 272.818, 'duration': 4.243}, {'end': 281.845, 'text': 'So anything nested inside the layout component is represented by the outlet.', 'start': 277.141, 'duration': 4.704}], 'summary': 'Configuring route components, importing components, and nesting with react router dom.', 'duration': 23.758, 'max_score': 197.598, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY197598.jpg'}, {'end': 394.592, 'src': 'embed', 'start': 372.759, 'weight': 3, 'content': [{'end': 381.323, 'text': "So, now that we have all of these other components inside of the layout component, we've got a group here that i labeled as public.", 'start': 372.759, 'duration': 8.564}, {'end': 382.704, 'text': "we'll want to keep these public.", 'start': 381.323, 'duration': 1.381}, {'end': 389.889, 'text': 'we have the login page, the register page, a link page so we can just navigate and try out the other routes,', 'start': 382.704, 'duration': 7.185}, {'end': 394.592, 'text': 'and then an unauthorized page that will show when someone is not authorized.', 'start': 389.889, 'duration': 4.703}], 'summary': 'Layout component includes login, register, link, and unauthorized pages for user navigation.', 'duration': 21.833, 'max_score': 372.759, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY372759.jpg'}, {'end': 459.871, 'src': 'embed', 'start': 434.68, 'weight': 4, 'content': [{'end': 440.523, 'text': "Okay, and with our application started, we are at the home component right now because it's not protected.", 'start': 434.68, 'duration': 5.843}, {'end': 442.704, 'text': 'And we can go to the editor page.', 'start': 440.723, 'duration': 1.981}, {'end': 444.925, 'text': 'We can go to the admin page.', 'start': 443.344, 'duration': 1.581}, {'end': 446.826, 'text': 'We can even go to the lounge.', 'start': 445.485, 'duration': 1.341}, {'end': 448.347, 'text': 'Nothing is protected right now.', 'start': 447.006, 'duration': 1.341}, {'end': 449.587, 'text': 'So all links are working.', 'start': 448.407, 'duration': 1.18}, {'end': 450.928, 'text': 'We go to the link page.', 'start': 449.768, 'duration': 1.16}, {'end': 452.069, 'text': "Here's the login.", 'start': 451.128, 'duration': 0.941}, {'end': 454.47, 'text': 'We can go back and go to the register as well.', 'start': 452.089, 'duration': 2.381}, {'end': 456.15, 'text': "Everything's available.", 'start': 455.17, 'duration': 0.98}, {'end': 459.871, 'text': 'And this lets us know our route paths are working.', 'start': 456.57, 'duration': 3.301}], 'summary': 'All application links are currently accessible and functioning correctly, indicating that route paths are working.', 'duration': 25.191, 'max_score': 434.68, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY434680.jpg'}], 'start': 38.411, 'title': 'Creating protected routes and implementing react router dom v6', 'summary': 'Demonstrates creating protected routes with react router v6, including role-based user permissions, targeting intermediate react developers, and separate tutorials for login and register forms and the node backend for authentication. it also covers adding react router dom v6 to package json, configuring index.js file, implementing the layout component, and defining public and protected routes, emphasizing functionalities and components added.', 'chapters': [{'end': 81.255, 'start': 38.411, 'title': 'Creating protected routes with react router v6', 'summary': 'Demonstrates how to create protected routes with react router version 6, including role-based user permissions, targeting intermediate level react developers who have completed beginner courses, and separate tutorials for login and register forms and the node backend for authentication.', 'duration': 42.844, 'highlights': ['The chapter covers creating protected routes with React Router version 6 and implementing role-based user permissions, targeting intermediate level React developers who have completed beginner courses.', 'Separate tutorials are available for the login and register forms, as well as the node backend used for authentication.']}, {'end': 456.15, 'start': 81.475, 'title': 'Implementing react router dom v6', 'summary': 'Covers the process of adding react router dom version 6 to the package json, configuring the index.js file, implementing the layout component, and defining public and protected routes, with an emphasis on the functionalities and components added.', 'duration': 374.675, 'highlights': ['React Router DOM version 6.2.1 is added to the package JSON.', 'Configuration of the index.js file to import and apply browser router and routes from React Router.', 'Implementation of the layout component and nesting of components using the outlet component.', 'Definition of public and protected routes for different user-based permissions, including components for login, register, and unauthorized access.', 'Verification of the accessibility and functionality of the implemented routes by starting the application and testing various links and components.']}], 'duration': 417.739, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY38411.jpg', 'highlights': ['The chapter covers creating protected routes with React Router version 6 and implementing role-based user permissions, targeting intermediate level React developers who have completed beginner courses.', 'Separate tutorials are available for the login and register forms, as well as the node backend used for authentication.', 'Configuration of the index.js file to import and apply browser router and routes from React Router.', 'Definition of public and protected routes for different user-based permissions, including components for login, register, and unauthorized access.', 'Verification of the accessibility and functionality of the implemented routes by starting the application and testing various links and components.', 'React Router DOM version 6.2.1 is added to the package JSON.', 'Implementation of the layout component and nesting of components using the outlet component.']}, {'end': 645.625, 'segs': [{'end': 507.427, 'src': 'embed', 'start': 479.634, 'weight': 0, 'content': [{'end': 483.415, 'text': "We don't want to see if user and so on before our routes.", 'start': 479.634, 'duration': 3.781}, {'end': 489.378, 'text': "we want to handle this in a cleaner way and the way that's really recommended by the react router docs.", 'start': 483.815, 'duration': 5.563}, {'end': 495.641, 'text': "so that said, we need to create another directory over here and let's call this directory hooks.", 'start': 489.378, 'duration': 6.263}, {'end': 502.625, 'text': "inside the hooks directory let's create a file called use auth with a capital a for auth, dot js.", 'start': 495.641, 'duration': 6.984}, {'end': 507.427, 'text': "inside of use auth we're going to import use context from react.", 'start': 502.625, 'duration': 4.802}], 'summary': 'Implement recommended react router approach by creating hooks directory with useauth.js file.', 'duration': 27.793, 'max_score': 479.634, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY479634.jpg'}, {'end': 589.059, 'src': 'embed', 'start': 556.944, 'weight': 1, 'content': [{'end': 558.845, 'text': 'use context auth context.', 'start': 556.944, 'duration': 1.901}, {'end': 567.408, 'text': 'We can kind of eliminate those steps by just defining this custom hook so we can use auth and pull what we need from our auth context.', 'start': 559.225, 'duration': 8.183}, {'end': 570.57, 'text': 'And we can see how this works inside of the login component.', 'start': 567.668, 'duration': 2.902}, {'end': 572.13, 'text': "So let's go to the login component.", 'start': 570.63, 'duration': 1.5}, {'end': 576.072, 'text': 'And here we had use context imported, so we can remove that.', 'start': 572.371, 'duration': 3.701}, {'end': 580.015, 'text': 'We were also importing the auth context, so we can remove that.', 'start': 576.233, 'duration': 3.782}, {'end': 584.277, 'text': "So now let's just import useAuth from our hooks directory.", 'start': 580.415, 'duration': 3.862}, {'end': 589.059, 'text': 'And once we have that imported, we find where we are actually using it in the component.', 'start': 584.897, 'duration': 4.162}], 'summary': 'Create custom hook to simplify authentication process, improving efficiency and reducing redundant imports.', 'duration': 32.115, 'max_score': 556.944, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY556944.jpg'}, {'end': 622.808, 'src': 'heatmap', 'start': 552.482, 'weight': 2, 'content': [{'end': 556.944, 'text': 'import the auth context and then set our context equal to this.', 'start': 552.482, 'duration': 4.462}, {'end': 558.845, 'text': 'use context auth context.', 'start': 556.944, 'duration': 1.901}, {'end': 567.408, 'text': 'We can kind of eliminate those steps by just defining this custom hook so we can use auth and pull what we need from our auth context.', 'start': 559.225, 'duration': 8.183}, {'end': 570.57, 'text': 'And we can see how this works inside of the login component.', 'start': 567.668, 'duration': 2.902}, {'end': 572.13, 'text': "So let's go to the login component.", 'start': 570.63, 'duration': 1.5}, {'end': 576.072, 'text': 'And here we had use context imported, so we can remove that.', 'start': 572.371, 'duration': 3.701}, {'end': 580.015, 'text': 'We were also importing the auth context, so we can remove that.', 'start': 576.233, 'duration': 3.782}, {'end': 584.277, 'text': "So now let's just import useAuth from our hooks directory.", 'start': 580.415, 'duration': 3.862}, {'end': 589.059, 'text': 'And once we have that imported, we find where we are actually using it in the component.', 'start': 584.897, 'duration': 4.162}, {'end': 591.581, 'text': 'So we were bringing in the setAuth function.', 'start': 589.159, 'duration': 2.422}, {'end': 594.842, 'text': 'setting that equal to use context, auth context.', 'start': 592.421, 'duration': 2.421}, {'end': 599.044, 'text': "so here we'll just say use auth and save, and that's all there is to it.", 'start': 594.842, 'duration': 4.202}, {'end': 605.408, 'text': "and we wanted to do this because we're going to use this global auth in other parts of the application as well.", 'start': 599.044, 'duration': 6.364}, {'end': 607.129, 'text': 'so this just makes it much easier.', 'start': 605.408, 'duration': 1.721}, {'end': 610.51, 'text': "and now we're ready to create the component that will help us protect our routes.", 'start': 607.129, 'duration': 3.381}, {'end': 619.305, 'text': "so let's create one more new component over here, and we'll call this require auth with a capital r and capital a, And once we have that defined,", 'start': 610.51, 'duration': 8.795}, {'end': 622.808, 'text': "we're going to import several things again from React Router.", 'start': 619.305, 'duration': 3.503}], 'summary': 'Create custom hook useauth to simplify auth context usage in login component and other parts of application.', 'duration': 70.326, 'max_score': 552.482, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY552482.jpg'}], 'start': 456.57, 'title': 'Implementing global authentication in react', 'summary': "Explains updating the global auth state in react router, creating a 'useauth' custom hook, and implementing global authentication in a react application, focusing on clean and recommended approaches, streamlining process, and simplifying code within the login component.", 'chapters': [{'end': 556.944, 'start': 456.57, 'title': 'Update global auth state in react router', 'summary': "Highlights the process of updating the global auth state in react router by creating a 'useauth' custom hook, emphasizing the clean and recommended approach while avoiding conditional logic within routes.", 'duration': 100.374, 'highlights': ["Creating a 'useAuth' custom hook to handle global auth state in a cleaner and recommended way, which saves time and avoids conditional logic within routes.", "The 'useAuth' hook involves importing 'useContext' from React, importing the auth context, defining the hook, and setting the default export.", 'The approach aims to avoid conditional logic within routes and follows the recommended method documented in the react router docs.']}, {'end': 599.044, 'start': 556.944, 'title': 'Context-based custom hook for authentication', 'summary': 'Demonstrates creating a custom hook to streamline authentication context usage, resulting in the elimination of unnecessary steps and the simplification of code within the login component.', 'duration': 42.1, 'highlights': ['A custom hook is defined to utilize the auth context and retrieve necessary data, leading to the removal of redundant steps within the login component.', 'Importing useAuth from the hooks directory replaces the need for importing and using use context and auth context, simplifying the code.', 'By utilizing the custom hook useAuth, the process of obtaining and using the setAuth function becomes more concise and streamlined.']}, {'end': 645.625, 'start': 599.044, 'title': 'Implementing global authentication in react app', 'summary': 'Discusses the implementation of global authentication in a react application, aiming to streamline the process and prepare for creating a component to protect routes, requiring the import of several elements from react router and the useauth hook.', 'duration': 46.581, 'highlights': ['The chapter discusses the implementation of global authentication in a React application, aiming to streamline the process and prepare for creating a component to protect routes, requiring the import of several elements from React Router and the useAuth hook.', 'Creating a component to protect routes, aiming for a streamlined process in using global authentication throughout the application.', 'Importing elements from React Router, including useLocation, Navigate, and Outlet, along with the useAuth hook for defining the requireAuth component.']}], 'duration': 189.055, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY456570.jpg', 'highlights': ["Creating a 'useAuth' custom hook to handle global auth state in a cleaner and recommended way, which saves time and avoids conditional logic within routes.", 'A custom hook is defined to utilize the auth context and retrieve necessary data, leading to the removal of redundant steps within the login component.', 'The chapter discusses the implementation of global authentication in a React application, aiming to streamline the process and prepare for creating a component to protect routes, requiring the import of several elements from React Router and the useAuth hook.']}, {'end': 1156.394, 'segs': [{'end': 676.873, 'src': 'embed', 'start': 645.665, 'weight': 1, 'content': [{'end': 647.207, 'text': 'So require, there we go.', 'start': 645.665, 'duration': 1.542}, {'end': 651.97, 'text': "auth and we're going to create two versions of this today.", 'start': 648.087, 'duration': 3.883}, {'end': 659.996, 'text': "the first version will be a little simpler, more like it's a boolean basically whether the user is just logged in or not.", 'start': 651.97, 'duration': 8.026}, {'end': 666.781, 'text': "now, later on, we'll come back and change this and it will actually support role-based permissions for the users.", 'start': 659.996, 'duration': 6.785}, {'end': 676.873, 'text': 'right now we just want to pull in the auth from use auth, And then we also need the location.', 'start': 666.781, 'duration': 10.092}], 'summary': 'Creating two versions of auth: simple boolean for login status, then role-based permissions.', 'duration': 31.208, 'max_score': 645.665, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY645665.jpg'}, {'end': 741.237, 'src': 'embed', 'start': 715.427, 'weight': 4, 'content': [{'end': 721.591, 'text': 'so this require auth component can protect all the child components that are nested inside of it.', 'start': 715.427, 'duration': 6.164}, {'end': 725.452, 'text': 'And so only if we have a user will it show these components.', 'start': 722.251, 'duration': 3.201}, {'end': 733.655, 'text': "After that, let's have the false part of the ternary and here we'll have the navigate that we imported and we'll say to,", 'start': 726.332, 'duration': 7.323}, {'end': 737.636, 'text': "and we'll just send anyone that is not logged in to the login page.", 'start': 733.655, 'duration': 3.981}, {'end': 741.237, 'text': 'But we also need to put a couple of attributes.', 'start': 738.076, 'duration': 3.161}], 'summary': 'Require auth component protects nested components, redirects non-logged in users to the login page.', 'duration': 25.81, 'max_score': 715.427, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY715427.jpg'}, {'end': 812.714, 'src': 'heatmap', 'start': 773.65, 'weight': 0.753, 'content': [{'end': 779.596, 'text': "now there is something else we'll need to apply in the login component to make all of this work as it should as well,", 'start': 773.65, 'duration': 5.946}, {'end': 782.098, 'text': 'but this passes along that value.', 'start': 779.596, 'duration': 2.502}, {'end': 784.841, 'text': 'so we need that there as well too.', 'start': 782.098, 'duration': 2.743}, {'end': 794.002, 'text': "let's go ahead and put a semicolon there, and we need to export default, require auth and save.", 'start': 784.841, 'duration': 9.161}, {'end': 799.106, 'text': "OK, now let's go to the app component and apply this new require auth component.", 'start': 794.543, 'duration': 4.563}, {'end': 801.307, 'text': 'So then we need to import it as well.', 'start': 799.206, 'duration': 2.101}, {'end': 806.51, 'text': "And I'll put it just above the routes and route import so it's with the other components.", 'start': 801.327, 'duration': 5.183}, {'end': 809.572, 'text': 'This will be require auth.', 'start': 807.291, 'duration': 2.281}, {'end': 812.714, 'text': 'And it comes from the components directory and require auth.', 'start': 809.732, 'duration': 2.982}], 'summary': 'Implement require auth in login and app components for authentication.', 'duration': 39.064, 'max_score': 773.65, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY773650.jpg'}, {'end': 908.089, 'src': 'heatmap', 'start': 862.93, 'weight': 0.811, 'content': [{'end': 866.592, 'text': "So let's just check these routes to see if we can access them.", 'start': 862.93, 'duration': 3.662}, {'end': 869.863, 'text': 'Nope, takes us straight to the login.', 'start': 867.981, 'duration': 1.882}, {'end': 875.647, 'text': "If we try to go home, try the editor's page, straight to the login, and the admin page.", 'start': 870.063, 'duration': 5.584}, {'end': 877.969, 'text': 'Once again, straight to the login.', 'start': 876.307, 'duration': 1.662}, {'end': 881.411, 'text': 'And notice how we were able to go back to where we were before.', 'start': 878.249, 'duration': 3.162}, {'end': 889.557, 'text': "And that is because we provided that extra attribute in require auth and I'll resize this so we can see it again.", 'start': 881.471, 'duration': 8.086}, {'end': 892.439, 'text': 'that gave the from location and replace.', 'start': 889.557, 'duration': 2.882}, {'end': 894.441, 'text': "So let's temporarily remove these.", 'start': 892.559, 'duration': 1.882}, {'end': 899.424, 'text': 'and save once again and see how the app responds differently.', 'start': 894.921, 'duration': 4.503}, {'end': 908.089, 'text': "now let's go to home and it took us to the login page and i'll click back and i'm still going back to the login.", 'start': 899.424, 'duration': 8.665}], 'summary': "Unable to access routes, always redirected to the login page due to 'require auth' attribute.", 'duration': 45.159, 'max_score': 862.93, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY862930.jpg'}, {'end': 899.424, 'src': 'embed', 'start': 870.063, 'weight': 0, 'content': [{'end': 875.647, 'text': "If we try to go home, try the editor's page, straight to the login, and the admin page.", 'start': 870.063, 'duration': 5.584}, {'end': 877.969, 'text': 'Once again, straight to the login.', 'start': 876.307, 'duration': 1.662}, {'end': 881.411, 'text': 'And notice how we were able to go back to where we were before.', 'start': 878.249, 'duration': 3.162}, {'end': 889.557, 'text': "And that is because we provided that extra attribute in require auth and I'll resize this so we can see it again.", 'start': 881.471, 'duration': 8.086}, {'end': 892.439, 'text': 'that gave the from location and replace.', 'start': 889.557, 'duration': 2.882}, {'end': 894.441, 'text': "So let's temporarily remove these.", 'start': 892.559, 'duration': 1.882}, {'end': 899.424, 'text': 'and save once again and see how the app responds differently.', 'start': 894.921, 'duration': 4.503}], 'summary': "Testing navigation to editor's, login, and admin pages with added attributes for authentication.", 'duration': 29.361, 'max_score': 870.063, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY870063.jpg'}, {'end': 989.422, 'src': 'embed', 'start': 962.251, 'weight': 2, 'content': [{'end': 969.372, 'text': "replacing that history in the navigation works let's go ahead and apply the changes that we need to to the login component as well.", 'start': 962.251, 'duration': 7.121}, {'end': 975.234, 'text': 'So once we log in, it can take us to where we were headed And of course, it will remember where we came from.', 'start': 969.452, 'duration': 5.782}, {'end': 978.816, 'text': "At the top, let's import three things from React Router.", 'start': 975.595, 'duration': 3.221}, {'end': 989.422, 'text': "We're going to import link with a capital L, use navigate, and also we're going to import use location.", 'start': 978.916, 'duration': 10.506}], 'summary': 'Updating navigation to remember user history and improve login component.', 'duration': 27.171, 'max_score': 962.251, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY962251.jpg'}, {'end': 1115.384, 'src': 'heatmap', 'start': 1032.599, 'weight': 0.726, 'content': [{'end': 1036.021, 'text': "And then we'll also see if it has a path name property.", 'start': 1032.599, 'duration': 3.422}, {'end': 1039.064, 'text': "And if it does, that's what from will be.", 'start': 1036.863, 'duration': 2.201}, {'end': 1048.069, 'text': "Other than that, we'll set an or and we'll just set it to the root path, which would take the user back to the homepage otherwise.", 'start': 1039.765, 'duration': 8.304}, {'end': 1052.093, 'text': 'But what we really want to do is get where they came from.', 'start': 1048.17, 'duration': 3.923}, {'end': 1060.759, 'text': "And then we want to scroll down to the handle, submit function and change what is inside of there as far as where we're navigating our user.", 'start': 1052.113, 'duration': 8.646}, {'end': 1065.361, 'text': 'two so after the form is cleared out, then we want to navigate away.', 'start': 1060.759, 'duration': 4.602}, {'end': 1068.663, 'text': 'so instead of just setting the success to true,', 'start': 1065.361, 'duration': 3.302}, {'end': 1080.309, 'text': "we'll put navigate here and we pass in that from value and then there's an object and we'll set the replace value to true and we can save this.", 'start': 1068.663, 'duration': 11.646}, {'end': 1082.87, 'text': 'i guess i could put a semicolon over here to match.', 'start': 1080.309, 'duration': 2.561}, {'end': 1089.773, 'text': 'so this essentially replaces that success page that was in the previous tutorial for the login.', 'start': 1082.87, 'duration': 6.903}, {'end': 1101.957, 'text': 'so, given that we can go ahead and remove the success and set success state that was in the login and we can also remove that display from the jsx,', 'start': 1089.773, 'duration': 12.184}, {'end': 1109.801, 'text': "so that removes our fragment and it removes our turn area there and we'll need to do that at the bottom as well.", 'start': 1101.957, 'duration': 7.844}, {'end': 1115.384, 'text': "and then we should be good to save and we're back to where we expect it to be.", 'start': 1109.801, 'duration': 5.583}], 'summary': 'Updating navigation logic for form submission and removing unnecessary code.', 'duration': 82.785, 'max_score': 1032.599, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY1032598.jpg'}], 'start': 645.665, 'title': 'Implementing user authentication, authorization, route protection, and react router navigation', 'summary': "Involves creating a component for user authentication and authorization, implementing route protection for specific routes, and utilizing react router for seamless navigation. it includes implementing a boolean check for user login status, protecting nested child components, adding route protection for unauthorized users, and enabling authorized users to access specific routes. additionally, it covers implementing role-based permissions, updating the login component to remember user's navigation history, and utilizing react router for seamless navigation.", 'chapters': [{'end': 848.863, 'start': 645.665, 'title': 'Implementing user authentication and authorization', 'summary': "Involves creating a component to handle user authentication and authorization by implementing a boolean check for user login status and protecting nested child components based on user login status, using the 'require auth' component.", 'duration': 203.198, 'highlights': ['Creating a component to handle user authentication and authorization', 'Implementing a boolean check for user login status', 'Protecting nested child components based on user login status']}, {'end': 943.388, 'start': 849.003, 'title': 'Implementing route protection', 'summary': 'Demonstrates implementing route protection by adding an extra attribute in require auth, which ensures that unauthorized users are redirected to the login page and enables authorized users to access specific routes, such as home, editor, and admin, seamlessly.', 'duration': 94.385, 'highlights': ['Adding an extra attribute in require auth ensures unauthorized users are redirected to the login page and enables authorized users to access specific routes seamlessly', 'The need to apply the extra attribute to the login page to enable direct access to the desired location after logging in', 'Demonstrating the difference in app response after temporarily removing the extra attribute in require auth']}, {'end': 1156.394, 'start': 943.408, 'title': 'React router navigation', 'summary': "Discusses implementing role-based permissions, updating the login component to remember the user's navigation history, and utilizing react router for seamless navigation, with a focus on replacing the history in the navigation and remembering the user's intended destination.", 'duration': 212.986, 'highlights': ['The chapter discusses implementing role-based permissions', "Updating the login component to remember the user's navigation history", 'Utilizing React Router for seamless navigation']}], 'duration': 510.729, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY645665.jpg', 'highlights': ['Adding an extra attribute in require auth ensures unauthorized users are redirected to the login page and enables authorized users to access specific routes seamlessly', 'The chapter discusses implementing role-based permissions', "Updating the login component to remember the user's navigation history", 'Utilizing React Router for seamless navigation', 'Creating a component to handle user authentication and authorization', 'Implementing a boolean check for user login status', 'Protecting nested child components based on user login status', 'The need to apply the extra attribute to the login page to enable direct access to the desired location after logging in', 'Demonstrating the difference in app response after temporarily removing the extra attribute in require auth']}, {'end': 1841.221, 'segs': [{'end': 1227.33, 'src': 'embed', 'start': 1178.429, 'weight': 1, 'content': [{'end': 1180.211, 'text': "So now I'll enter in my name.", 'start': 1178.429, 'duration': 1.782}, {'end': 1182.432, 'text': "And I'll enter in my password.", 'start': 1180.231, 'duration': 2.201}, {'end': 1186.855, 'text': 'and sign in and it took me to the home page.', 'start': 1183.613, 'duration': 3.242}, {'end': 1188.396, 'text': 'So that is great.', 'start': 1187.295, 'duration': 1.101}, {'end': 1189.516, 'text': 'Let me sign out again.', 'start': 1188.436, 'duration': 1.08}, {'end': 1195.039, 'text': "Let's say I wanted to go to the editor's page because my user, Dave, is an editor.", 'start': 1189.596, 'duration': 5.443}, {'end': 1205.138, 'text': "So I enter in my password, and it takes me straight to the editor's page, even though I was redirected to the sign-in page first.", 'start': 1197.072, 'duration': 8.066}, {'end': 1208.6, 'text': "And so that's why we're modifying that history with React Router.", 'start': 1205.278, 'duration': 3.322}, {'end': 1212.263, 'text': "Okay, I'm going to sign out again, but now I'm going to expand the webpage.", 'start': 1208.78, 'duration': 3.483}, {'end': 1219.167, 'text': "Then you can right-click and choose Inspect, or you can do Control Shift I, And let's look at the console.", 'start': 1212.743, 'duration': 6.424}, {'end': 1222.969, 'text': "OK, you can see what I'm getting here in the console when I log in.", 'start': 1219.607, 'duration': 3.362}, {'end': 1227.33, 'text': "I'm getting sent back not only an access token, but also roles.", 'start': 1223.489, 'duration': 3.841}], 'summary': 'Logging in redirects to home page. modifying history with react router. access token and roles received.', 'duration': 48.901, 'max_score': 1178.429, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY1178429.jpg'}, {'end': 1275.452, 'src': 'embed', 'start': 1250.782, 'weight': 0, 'content': [{'end': 1260.187, 'text': "We'll come back to Visual Studio Code, and we can modify this require auth to now use those roles that are being stored inside of the auth state.", 'start': 1250.782, 'duration': 9.405}, {'end': 1264.77, 'text': "OK, I'm going to go ahead and hide the file tree too, just so nothing runs off the screen here.", 'start': 1260.567, 'duration': 4.203}, {'end': 1269.691, 'text': "And with this requireAuth component, we're going to receive a prop.", 'start': 1265.53, 'duration': 4.161}, {'end': 1273.792, 'text': 'And this prop is going to be allowedRoles.', 'start': 1269.951, 'duration': 3.841}, {'end': 1275.452, 'text': 'So this will get passed in.', 'start': 1274.012, 'duration': 1.44}], 'summary': 'Modifying requireauth in visual studio code to use stored roles.', 'duration': 24.67, 'max_score': 1250.782, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY1250782.jpg'}, {'end': 1439.273, 'src': 'embed', 'start': 1411.729, 'weight': 2, 'content': [{'end': 1424.327, 'text': "so this navigate is going to go to the unauthorized path And then let's go ahead and put in the same state,", 'start': 1411.729, 'duration': 12.598}, {'end': 1427.968, 'text': "because once again they didn't ask to go to the unauthorized path.", 'start': 1424.327, 'duration': 3.641}, {'end': 1429.329, 'text': "It's just where they ended up.", 'start': 1428.068, 'duration': 1.261}, {'end': 1431.69, 'text': "So we'll pass this along as well.", 'start': 1429.909, 'duration': 1.781}, {'end': 1435.011, 'text': "So the back button works, and that's important too.", 'start': 1431.87, 'duration': 3.141}, {'end': 1439.273, 'text': "OK, so now we've completed our requireAuth component that supports roles.", 'start': 1435.171, 'duration': 4.102}], 'summary': 'Implemented requireauth component supporting roles', 'duration': 27.544, 'max_score': 1411.729, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY1411729.jpg'}, {'end': 1841.221, 'src': 'embed', 'start': 1817.71, 'weight': 4, 'content': [{'end': 1823.953, 'text': 'but it has helped you understand how to apply role-based user permissions for your protected routes.', 'start': 1817.71, 'duration': 6.243}, {'end': 1830.636, 'text': 'Remember to keep striving for progress over perfection, and a little progress every day will go a very long way.', 'start': 1824.233, 'duration': 6.403}, {'end': 1835.878, 'text': "Please give this video a like if it's helped you, and thank you for watching and subscribing.", 'start': 1831.316, 'duration': 4.562}, {'end': 1837.399, 'text': "You're helping my channel grow.", 'start': 1836.038, 'duration': 1.361}, {'end': 1841.221, 'text': "Have a great day, and let's write more code together very soon.", 'start': 1837.959, 'duration': 3.262}], 'summary': "Learned role-based permissions for protected routes. strive for progress over perfection. like and subscribe to support the channel's growth.", 'duration': 23.511, 'max_score': 1817.71, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY1817710.jpg'}], 'start': 1156.394, 'title': 'Implementing role-based user permissions', 'summary': 'Discusses user authentication against a backend api, successful login, and role-based access with specific roles and values, demonstrating role-based user permissions using react router v6, and emphasizes the importance of progress over perfection.', 'chapters': [{'end': 1250.322, 'start': 1156.394, 'title': 'User authentication and role confirmation', 'summary': 'Discusses user authentication against a backend api, demonstrating successful login and role-based access with specific roles and values, and modifying history with react router.', 'duration': 93.928, 'highlights': ["The backend API sends back not only an access token but also user roles, with '2001' representing a user and '1984' representing an editor role.", 'The demonstration includes successful logins for both regular users and an editor, showcasing role-based access.', 'Modifying history with React Router is discussed in the context of redirecting users based on their roles after login.']}, {'end': 1841.221, 'start': 1250.782, 'title': 'React router v6 role-based user permissions', 'summary': 'Explains how to implement role-based user permissions using react router version 6, allowing users with specific roles to access certain paths, and highlights the importance of progress over perfection.', 'duration': 590.439, 'highlights': ['Implemented a requireAuth component to support roles and compare the values of two arrays for user authorization.', 'Demonstrated passing allowed roles array for each protected path in the app component, enabling role-based access control for different routes.', 'Utilized navigate function and go back functionality for unauthorized page, enabling users to navigate back to the previous page.']}], 'duration': 684.827, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/oUZjO00NkhY/pics/oUZjO00NkhY1156394.jpg', 'highlights': ['Implemented a requireAuth component for user authorization', 'Demonstrated successful logins for regular users and an editor', 'Utilized navigate function and go back functionality for unauthorized page', 'Discussed modifying history with React Router for role-based redirection', 'Emphasized the importance of progress over perfection in user authentication']}], 'highlights': ['Separate tutorials available for login and register forms, targeting intermediate React developers.', 'Creating protected routes with React Router v6 and implementing role-based user permissions.', "Creating 'useAuth' custom hook to handle global auth state in a cleaner way.", 'Demonstrated successful logins for regular users and an editor.', 'Adding extra attribute in require auth ensures unauthorized users are redirected to the login page.']}