Part 11 of The MERN Stack Project Series - In this lesson, we add user role-based access control and permissions to the React app of our MERN Stack Project. Role-based access control abstracts permissions from an individual user login and assigns them to user roles instead. This tutorial is not for beginners. If you are a beginner, check out my full courses all in one playlist here: ua-cam.com/play/PL0Zuz27SZ-6M1Uopt6_VL3gf3cpMnwavm.html
Hey Dave, thanks a whole lot for this course, it’s superb. But any chance you might give me a hand with?? ERROR Cannot destructure property ‘username’ of ‘decoded.UserInfo’ as it is undefined. at useAuth Everything else works fine, this prompt happens whenever i login a user and it only goes away when i refresh the page. But i reckon it has also prevented the final deployed code from proceeding further after login too. Thanks in advance fam!
Dave you are amazing. This is by far the best series I have seen on youtube. You are a legend my man. And to think this is for free? When I get my first paid software development gig, I owe you not one coffee, but ten or more. Thanks, thanks and more thanks.
I'm stuck in login page, I can't go back because the location it remember is the protected page so it redirect me back to login every time I click back arrow on chrome until I login.
25:04 when I console log the filter it returns without result, I might think cause there's no "username" field in my data. But the useAuth username return to a string which the staff who logged in. I then, change ..... => entities[noteId].user === username still cannot cause it tries to compare array of users id with a string. eg 2134tr4321, 21342141,123213 === Joe so I cant actually fetch Joe's notes. If there's a way to fetch Notes id.username. Or any solutions. Im stuck here for a week already. Any helps is appreciated. Thanks!
Hi Dave, Thank you for the excellent lesson. How do you get isManager/role name from token if the server only includes role number based on your previous express server? roles is an array with numbers and you have verify role middleware, but you never included the role name in the token. Did you make changes to the server where the access token now includes the role number and role name?
Amazing video,i have a doubt what if a hacker modifies the role or worse removes the protection of routes by disabling the wrapper component that protects the routes ?then he can gain access to protected routes ,right?so in that scenario ,the only way to protect unauthorized content would be be to Authorize the user for each request ?
There are endless "what if" scenarios with security. You can ramp up the security on this project by verifying auth on both the server (Node.js) and the client (frontend React).
Hi, Dave Gray I'm having trouble as I go along. The only thing that shows when I try to log out is the blank background color; however, if I refresh the page first, everything goes through without a hitch. The checkbox is always ticked; if I uncheck it, the local storage changes to false. I would greatly appreciate any suggestions you might make. Thank you.
@@nandakumart2331 Hello, you're correct. After seeing some fresh updates in the official documents. I uninstalled the version I was using and installed Dave's version it worked at last . Thank you for your assistance.
Hi Dave. Thanks for a great tutorial! I'm not sure if I’m getting things correct, but you are reading all the data (like notes) from mongodb and then filtering them on a view? Isn't that a little unsecure? And what if there is a large amount of data to read. Wouldn’t it be a good idea to filter it at the request (controller) level and get only the notes from a specific user? That’s what I would do with a SQL database, but maybe it’s different with json db.
Been too long since I built this to remember the details, but filtering at the controller is a good idea when possible. Nothing wrong with security here, but if needing to scale larger, handling things server-side is always good. I remember this project / example being for a small computer shop.
Hey Dave, wonderful tutorial as usual. I followed you from redux to RTK to now closing out this killing MERN series. I found what's paying off well for beginners like me was to spend lots of extra time researching related knowledge around your coding paradigms & styles and trying to actualize the same functions in different ways:) Just wanted to point out one tiny thing at 24:46: const tableContent = ids?.length && filteredIds.map(noteId => ) It seems the && operator would return 0 if there is no note at all. Since createEntityAdapter would return an empty 'ids' array and then 'ids?.length' would return 0. The right side of && would return empty array too. This 0 would cause error in react. Thanks!
hey dave. been starting amd your videos are the cleanest thing around. please keep going. i have a question? or lets say a user story to be exact. could we attach a picture or a file to our note when we are creating it.? would we just add to our note model or make new ones? cheers!
Thank you, Nino! You could reference a file in your model several ways. For example, you might upload your images to an AWS bucket and just store the id and url of the image or file in your model. Or you might only have a few files to upload and just send them straight to your Node.js server like I show here: ua-cam.com/video/4pmkQjsKJ-U/v-deo.html ...again, I would probably just store the filename in my model and reference it when needed.
Hi Dave, first of all thank you for putting a lot of effort in all these tutorials, god bless. But i have a little question about jwt-decode. Is there a reason to not return all those user information alongside with the accesstoken since we already have those information in our backend ?
I'm not sure that I understand your question? Are you asking why we return the user information? The frontend needs the user information to handle any permissions for the frontend. Also, if you refresh the app, you lose all current state - and you need the backend to send the current user info back after the refresh token is received.
@@DaveGrayTeachesCode What i meant was that, when we hit the /auth/refresh or /auth/login route in our backend we send the user information via the access token. Can we just send it like res.json({token:accessToken,userInfo:{id_:foundUser._id,...}}) so that we don't need to decode the token in frontend. Or am i just missing something here ?
Hi Dave, A quick question- How do I create an admin again at this stage to log in etc? I actually deleted the admin created in the previous videos when testing out Postman
If you have deleted all users that can create a user, you will then need to disable the verifyJWT middleware in the backend code and use Postman (or similar) to create an admin user. I believe I show how to do this with Postman in lesson 4.
@@DaveGrayTeachesCode I wanted to ask if you would perhaps cover a video on how you would perform a snapshot test and appropriate unit tests for both the front-end and back-end of the application? Any guidance here?
hey Dave I just started learning from your courses I wanted to ask if I can take your react course with react 18 or is it going to create problem because your course is in react 17 ????
Great question! You can, but you will need to make an adjustment or two even though my course is just over one year old. You could also just set your package.json to React 17 for the course as well. The biggest difference is not React 18 but React Router v6 was released shortly after my course. I have an update video for that linked in the course description, too.
I can only guess what may be different in your code. I think it was lesson 2 in this series where I go over how to set up CORS with allowed origins and cors options. Please review that and compare to your code.
@@DaveGrayTeachesCode Thank you so much Dave! Just completed lesson 12 and everything else is working correctly just this CORS error for delete. Will review and get back to you. Kind regards.
Phew all working correctly! So there was a CORS Chrome extension installed on this machine and this was causing the error. Thank you so much Dave for this excellent project!
I think the next one is the last - just mentioned near the end of this one 😃 We will be adding some finishing touches, refactoring, deploying and reviewing the project.
I _may_ do another project like this someday and use TS along the way. The Redux docs are starting to add TS also. They do have an auth section in the docs with a code sandbox in TS that might help. Here is a link to their auth file: codesandbox.io/s/github/reduxjs/redux-toolkit/tree/master/examples/query/react/authentication?from-embed=&file=/src/app/services/auth.ts
Great video like always! But seems I did something wrong somewhere like my console log is full of "react_devtools_backend.js:4026 TypeError: responseData.map is not a function" but the source says "react_devtools_backend.js:4026" so really confuse right now. 😰
While not in this series, I do have a video on pagination here: ua-cam.com/video/9ZbdwL5NSuQ/v-deo.html ...and in my React course, I show how to filter blog posts - you could do the same with the notes in this app: ua-cam.com/video/RVFAyFWO4go/v-deo.html
@@DaveGrayTeachesCode Could you do your testing tutorials using this MERN project please? 🙏🏾🙏🏾 Proper testing of redux and rtk query is what is sorely needed cos no one is doing tutorials on it 😞
Part 11 of The MERN Stack Project Series - In this lesson, we add user role-based access control and permissions to the React app of our MERN Stack Project. Role-based access control abstracts permissions from an individual user login and assigns them to user roles instead. This tutorial is not for beginners. If you are a beginner, check out my full courses all in one playlist here: ua-cam.com/play/PL0Zuz27SZ-6M1Uopt6_VL3gf3cpMnwavm.html
Hey Dave, thanks a whole lot for this course, it’s superb. But any chance you might give me a hand with??
ERROR
Cannot destructure property ‘username’ of ‘decoded.UserInfo’ as it is undefined.
at useAuth
Everything else works fine, this prompt happens whenever i login a user and it only goes away when i refresh the page. But i reckon it has also prevented the final deployed code from proceeding further after login too.
Thanks in advance fam!
Dave you are amazing. This is by far the best series I have seen on youtube. You are a legend my man. And to think this is for free? When I get my first paid software development gig, I owe you not one coffee, but ten or more. Thanks, thanks and more thanks.
Thank you for the kind words! 💯 I know you will get your first dev gig. A little progress every day! 🚀
Thanks
You're welcome! And thank you for the support! 💯🙏
I'm stuck in login page, I can't go back because the location it remember is the protected page so it redirect me back to login every time I click back arrow on chrome until I login.
Thanks!
And thank you again for the support!! 🙏🙏
Thank you for The Best Tutorial 🤓🤓
You're welcome! 💯
25:04 when I console log the filter it returns without result, I might think cause there's no "username" field in my data. But the useAuth username return to a string which the staff who logged in.
I then, change ..... => entities[noteId].user === username
still cannot cause it tries to compare array of users id with a string. eg 2134tr4321, 21342141,123213 === Joe
so I cant actually fetch Joe's notes. If there's a way to fetch Notes id.username. Or any solutions. Im stuck here for a week already. Any helps is appreciated. Thanks!
As always, excellent lesson from a great teacher!
Thank you very much!
Hi Dave, Thank you for the excellent lesson. How do you get isManager/role name from token if the server only includes role number based on your previous express server?
roles is an array with numbers and you have verify role middleware, but you never included the role name in the token. Did you make changes to the server where the access token now includes the role number and role name?
You are excellent teacher!!!!
Amazing video,i have a doubt what if a hacker modifies the role or worse removes the protection of routes by disabling the wrapper component that protects the routes ?then he can gain access to protected routes ,right?so in that scenario ,the only way to protect unauthorized content would be be to Authorize the user for each request ?
There are endless "what if" scenarios with security. You can ramp up the security on this project by verifying auth on both the server (Node.js) and the client (frontend React).
Hi, Dave Gray
I'm having trouble as I go along. The only thing that shows when I try to log out is the blank background color; however, if I refresh the page first, everything goes through without a hitch. The checkbox is always ticked; if I uncheck it, the local storage changes to false. I would greatly appreciate any suggestions you might make. Thank you.
it is due to version of redux and redux toolkit
@@nandakumart2331 Hello, you're correct. After seeing some fresh updates in the official documents. I uninstalled the version I was using and installed Dave's version it worked at last . Thank you for your assistance.
Hi Dave. Thanks for a great tutorial! I'm not sure if I’m getting things correct, but you are reading all the data (like notes) from mongodb and then filtering them on a view? Isn't that a little unsecure? And what if there is a large amount of data to read. Wouldn’t it be a good idea to filter it at the request (controller) level and get only the notes from a specific user? That’s what I would do with a SQL database, but maybe it’s different with json db.
Been too long since I built this to remember the details, but filtering at the controller is a good idea when possible. Nothing wrong with security here, but if needing to scale larger, handling things server-side is always good. I remember this project / example being for a small computer shop.
Thank you for this video, it really helped me figure out auth😊 Greetings from Ukraine
Awesome content, thank you, Dave
Glad you liked it!
which theme are you using? Bro!!
Hey Dave, wonderful tutorial as usual. I followed you from redux to RTK to now closing out this killing MERN series. I found what's paying off well for beginners like me was to spend lots of extra time researching related knowledge around your coding paradigms & styles and trying to actualize the same functions in different ways:) Just wanted to point out one tiny thing at 24:46:
const tableContent = ids?.length && filteredIds.map(noteId => )
It seems the && operator would return 0 if there is no note at all. Since createEntityAdapter would return an empty 'ids' array and then 'ids?.length' would return 0. The right side of && would return empty array too. This 0 would cause error in react. Thanks!
Thanks and great note! Definitely something I would catch with Typescript. In this case, a conditional statement would be appropriate.
hey dave. been starting amd your videos are the cleanest thing around. please keep going.
i have a question? or lets say a user story to be exact. could we attach a picture or a file to our note when we are creating it.?
would we just add to our note model or make new ones? cheers!
Thank you, Nino! You could reference a file in your model several ways. For example, you might upload your images to an AWS bucket and just store the id and url of the image or file in your model. Or you might only have a few files to upload and just send them straight to your Node.js server like I show here: ua-cam.com/video/4pmkQjsKJ-U/v-deo.html ...again, I would probably just store the filename in my model and reference it when needed.
Hi Dave, first of all thank you for putting a lot of effort in all these tutorials, god bless. But i have a little question about jwt-decode. Is there a reason to not return all those user information alongside with the accesstoken since we already have those information in our backend ?
I'm not sure that I understand your question? Are you asking why we return the user information? The frontend needs the user information to handle any permissions for the frontend. Also, if you refresh the app, you lose all current state - and you need the backend to send the current user info back after the refresh token is received.
@@DaveGrayTeachesCode What i meant was that, when we hit the /auth/refresh or /auth/login route in our backend we send the user information via the access token. Can we just send it like res.json({token:accessToken,userInfo:{id_:foundUser._id,...}}) so that we don't need to decode the token in frontend. Or am i just missing something here ?
Thanks so much for the amazing content, I have learnt too much considering this is not a beginner course
Glad it was helpful!
Hi Dave,
A quick question- How do I create an admin again at this stage to log in etc? I actually deleted the admin created in the previous videos when testing out Postman
If you have deleted all users that can create a user, you will then need to disable the verifyJWT middleware in the backend code and use Postman (or similar) to create an admin user. I believe I show how to do this with Postman in lesson 4.
@@DaveGrayTeachesCode Thanks so much Dave I managed to get this right.
@@DaveGrayTeachesCode I wanted to ask if you would perhaps cover a video on how you would perform a snapshot test and appropriate unit tests for both the front-end and back-end of the application? Any guidance here?
@@chaltonprins2334 that could be another full series and that is a good idea!
Thank you! It's really helpful!!
Glad to hear that!
Thanks a lot Gray sir, for this valuable tuts
You've very welcome! 💯
Thank you. Again and again!
You're welcome! 💯
great teacher , thank you for educations
You are very welcome!
hey Dave
I just started learning from your courses
I wanted to ask if I can take your react course with react 18
or is it going to create problem because your course is in react 17 ????
Great question! You can, but you will need to make an adjustment or two even though my course is just over one year old. You could also just set your package.json to React 17 for the course as well. The biggest difference is not React 18 but React Router v6 was released shortly after my course. I have an update video for that linked in the course description, too.
Hi Dave, I am getting a blocked by CORS error when trying to delete a note. Do you have any pointers as to why this is happening? TIA Sai.
I can only guess what may be different in your code. I think it was lesson 2 in this series where I go over how to set up CORS with allowed origins and cors options. Please review that and compare to your code.
@@DaveGrayTeachesCode Thank you so much Dave! Just completed lesson 12 and everything else is working correctly just this CORS error for delete. Will review and get back to you. Kind regards.
Phew all working correctly! So there was a CORS Chrome extension installed on this machine and this was causing the error. Thank you so much Dave for this excellent project!
@@sailee5208 difficult problem to solve!
TOP!!! Thank YOU ❤️😊,I'm waiting for Your lessons everyday 💪
You're welcome! 💯
Hey dev how many parts in this series?
I think the next one is the last - just mentioned near the end of this one 😃 We will be adding some finishing touches, refactoring, deploying and reviewing the project.
Hi Dev, Thanks for your amazing content. Can you please write the reAuthBaseQuery part in typescript, please? Thank you
I _may_ do another project like this someday and use TS along the way. The Redux docs are starting to add TS also. They do have an auth section in the docs with a code sandbox in TS that might help. Here is a link to their auth file: codesandbox.io/s/github/reduxjs/redux-toolkit/tree/master/examples/query/react/authentication?from-embed=&file=/src/app/services/auth.ts
Great video like always! But seems I did something wrong somewhere like my console log is full of "react_devtools_backend.js:4026 TypeError: responseData.map is not a function" but the source says "react_devtools_backend.js:4026" so really confuse right now. 😰
I have not had that error. Please compare to my source code available in the course resources to find the difference.
Objects so anything with {} in JavaScript do not have the method .map(). It's only for Arrays, anything with [].
I have faced the same probolem. Any solution. I have copied everything so there is no scope to have different code. Tried several times without luck.
Issue solved. Just add return { ...note, username: user?.username }
Awesome tutorial thank you
You’re welcome! 💯
Hey Dave love the content could I ask/request for a video on filtering notes and pagination. Appreciate it, would like to see how you approach this.
While not in this series, I do have a video on pagination here: ua-cam.com/video/9ZbdwL5NSuQ/v-deo.html ...and in my React course, I show how to filter blog posts - you could do the same with the notes in this app: ua-cam.com/video/RVFAyFWO4go/v-deo.html
Awesome dev
🙏🙏
Nice Tutorial Sir, please can test be automated testing included in this tutorial or as a tutorial on it own. Will be greatly appreciated Sir
I'd like to do separate tutorials on testing. Thanks for the request!
@@DaveGrayTeachesCode Thanks very much Sir.
@@DaveGrayTeachesCode Could you do your testing tutorials using this MERN project please? 🙏🏾🙏🏾 Proper testing of redux and rtk query is what is sorely needed cos no one is doing tutorials on it 😞
@@stevereid636 good request!
Great sir
Thank you!
🎈
🚀
progress++
{2023-03-28}, {2023-05-19}
Thanks
Thank you for the support!