In this tutorial, we'll compare *authorization* to authentication. Once we understand both concepts, we'll expand the authorization given to our JWT tokens by including user role and permissions info in the process. If you're just starting with Node.js & Express, I suggest going to the beginning of this *Node.js for Beginners* playlist here: ua-cam.com/play/PL0Zuz27SZ-6PFkIxaJ6Xx_X46avTM1aYw.html
Great tutorial and a seriously underrated channel! I'm learning on my own and have been having a really hard time piecing these backend concepts together - this helped a lot. There's a lot of frontend tutorials out there, but not as many backends. Keep up the great work! subbed and liked
Wowwwww!!! this series of node and express tutorials is amazinggggg!!!!! I went through the whole series and really learned a lot even though I have used express for a long time. Thanks Dave, pls keep going for the excellent content, this is the best node &express tutorial on UA-cam.
Thank you for another fascinating lesson. A couple of notes: (1) 26:44 - It is not shown on screen but maybe you should consider to make it clear with hard-subs (because it might be confused) That in, the content of the Body tab is: {"id": 3, "firstname":"john", "lastname": "Doe"} (...took me awhile to figure it up, and it might ease others, so..) (2) 27:25 - Thank you for the clarification, but in this point people (such as myself) - Might already got confused and spent some time to figure it out on their own, So you might want to consider, again, to clear it up in the relevant (previous) video, with hard subs. * If those are too difficult to produce now, Then these clarifications might be helpful as notifications at the description (..which is quite busy already as is, but.. ..yeah).
Thanks - your comments may help others. UA-cam does not let me edit / change videos that have already been posted. I could continue to add to the description but as you mentioned, it already has a lot. Many provide suggestions and I may use these when I cover the topic again. 🚀
Awesome video series!! I've tried many times to understand node in more detail together with JWT Authorization and Authentication and this is the best resource available by far! Looking forward to taking more of your courses once you have your platform up and running!!
This is a very nice concept to apply access roles, I used to use similar concept before (saving user roles upon login process), everything worked nice until I encountered a case where a user was misbehaving and I needed to remove some roles, unfortunately there was no way to invalidate his access token and I had to wait for him to logout or for his session to get expired 🤦♂️😥 I really appreciate explaining the concept, this will make coding easier, Thanks Dave,
Awesome info. This tutorial and other ones you created provided all the answers I needed on how to integrate JWT into my project along with roles. I was cornfused before and now I'm less cornfused.
How do u automatically generate new access token from the server side with hit endpoint refresh token.. cos on d client once user is active d refresh token to generate new without re login.. pls
good idea with role codes! when it comes to verifying auth header, I prefer to destructure: const [bearer, token] = req.headers.authorization?.split(' '). Results in much cleaner code down the pipe.
@@DaveGrayTeachesCode I wonder how you configure a special role in this mix, which is owner - so a document can only be mutated/deleted by admin or owner
@@aram5642 on a per-document basis you would have to track the document owner and match it up, too. Otherwise, adding permissions for an admin only route to a delete endpoint should be much like the other restricted routes.
In the timeframe 09:48 you are obtaining the userroles from the founduser. But the userroles is also present in the decoded variable. can we assign the jwt userroles from founduser or decoded.userroles. both are fine?
Hey nice tutorials. I have a question. Why at 12:50 why need to modify request object and set user and user roles to it, when all this middleware does is check whether we have auth token?
If a bad user tried to hack our app by decoding his jwt and changing his userId and encoding it again and storing it in localstorage again, can he do it? Can't we detect that in the node server?
If I remember correctly, we are using jwt-decode middleware in this tutorial. (Reference: www.npmjs.com/package/jwt-decode) If a token is changed, it will be detected because they will not know the embedded secret key. You can also decode tokens at the following site and see how each part works: jwt.io/
Hi Dave! Great work, really enjoy your method of teaching and way of explaining everything. I consider myself more than a beginner but not advanced for sure, and I have found a lot of new information and new tips and tricks to take away from your lessons. I do have one question. I understand the process of passing the roles inside the JWT and validating them during the request process. However, what I don't quite understand, is why you use numbers associated to each role and not just level names (i.e. "admin" for Admin), I know you said that there are many constructs to role permissions, so maybe this is just one variation and there is no meaning behind it, but I was curious what your thoughts on it.
Thanks Robert! And great question - I think I only briefly mentioned it at best. And you are right that roles and permissions can be structured in many different ways. I've found they are often associated with codes or IDs. In this specific tutorial example, I briefly mentioned that a backend dev will not have control over how a frontend dev chooses to store the access token. While I believe an access token should only be kept in memory, others do put them in local storage or cookies that are not httpOnly. If someone got a JWT and decoded it (like you can at JWT.io), they can easily read the payload. I'd rather have a code or two in there instead of clearly stating this is an admin token for example. Just a bit of security through obscurity if the JWT is mishandled.
@@DaveGrayTeachesCode Thanks again! I had a feeling it was going to involve some bit of obscurity, but I wanted to make sure I didn't miss anything. This also allows you to know the roles without a database lookup for every API call. Nice! Again, great work, keep it up! I'm always looking for great content and something to learn, I'll be watching more and more of your channel.
Hi Dave , your explanations are just Perfect , Please, any chance to ses PHP and symfony series in a near futur please ? Thank you for your JS long video , definitly super great !
i think that you should prepare some slides about theory of each lecture, for example authentication , but anyway your nodejs express course is awesome and amazing , i hope that in the future you can make advanced course about nodejs .Tks very much !!!
If I were to need to update the user for an API post request -- for example, the user clicks a button, and something is changed on their user account -- would it make sense to just use the refresh token to lookup the user in the database like you demonstrate with the login and refresh routes? I'd prefer to use the user ID directly, but I imagine passing it through one of the tokens would be a security risk. Thanks!
hey dave may i know why have you used refreshTokenController in jwt authentication, i could not get the idea of creating another refresh route and generation the new access token
it's perfect content. I sent you message from twitter. I'm one of flutter and nodejs developer and I want to introduce you in my country (turkey) if we can make video together for 10 minutes for beginners I will be happy to translate for turkish franch and arabic! it's pleasure discovering your channel
Hello Dave. I'm sorry for another question: we check if there is access token in request and that it hasn't expired if access token has expired we need to refresh token and if cookie jwt is stored in database it will be refreshed but how it would work from frontend side? we have access token inside store we send GET request to secure route - it sends back 403 (token has expired) so we need to make one more request to /REFRESH (checkes cookie jwt and gives back new access) then rewrite our store token and then make this get request again? so if we work with redux we need middleware function which will implement at max 3-4 extra requests under the hood of every CRUD requests?
No, 3 or 4 extra requests are not necessary. You can see how it is implemented with Redux here: ua-cam.com/video/-JJFQ9bkUbo/v-deo.html ...for more on the frontend and using this strategy, I have a full React Auth playlist here: ua-cam.com/play/PL0Zuz27SZ-6PRCpm9clX0WiBEMB70FWwd.html
@@DaveGrayTeachesCode Thank you Dave. Yeah, have started your MERN course. I try to watch and repeat your every tutorial, they are extra helpful. You are the best!
Thanks, Dave, great video. Quick question... Is there any available service to which we can delegate the RBAC management to? For instance, if Cognito is taking care of the Authentication, do you know if there is any service for the Authorization part? Also what solution do you recommend for partial access levels? For instance, a user has Read access but only on his own posts? do these need to handle at the controller level or can we come up with a middleware that can filter response?
Thanks - You seem to be asking about Amazon services. It seems Amazon Cognito can handle RBAC: docs.aws.amazon.com/cognito/latest/developerguide/role-based-access-control.html Many different solutions are possible for partial access. I would consider different levels of roles for this.
In verifyRoles.js "Some" array method could have been used in place of chaining "map" and "find" when checking if rolesArray and req.roles contains the same elements.
Very rich playlist. However, I don't see the usecase for the accesstoken as response to the /login endpoint. First, because you advised that we should only store in memory, so we can't store in a state or context in the frontend that we can use to say access /employees endpoint later on. So maybe everytime we need to access the /employees endpoint, we first call /refresh and get an access token then call the /employees endpoint. I'd like anyone to point out a usecase for the accesstoken as response to the /login endpoint.
Hello! I have done this tutorial two times and also tried the testing with thunder client with the finished source code and am receiving the following error: Error: secretOrPrivateKey must have a value at Object.module.exports [as sign] (.../node_modules/jsonwebtoken/sign.js:107:20) The line of code in the /sign.js stated: if (!secretOrPrivateKey && options.algorithm !== 'none') { return failure(new Error('secretOrPrivateKey must have a value')); } I believe from looking online this is due to missing the contents of the .env file. Are you able to share what those would be? I've gone back through all the videos and am having a hard time finding where that was created and the variables inside it. Thank you!
The .env file just contains a secret variable value that you do not want to share in Github or other public resource. Confirm you have installed the dependency and that you have the dotenv required in the server file as shown in my source code. Any time you reference a variable found in the .env file, you reference it with process.env.VARIABLE_NAME (where you replace VARIABLE_NAME with whatever the actual name of your variable is). Otherwise, as you mentioned, going back through the code and tutorial can often uncover a small difference that creates an error when you follow along.
I have a Node.js upload video here: ua-cam.com/video/4pmkQjsKJ-U/v-deo.html Notifications can be handled in any stack you choose. I would likely use MERN.
Should i create different controllers for different roles?, eg: in some cases i need to use populate to get certain references within the document based on the role
No. Controllers are not based on roles. You usually route to a specific controller. You can control access to the route with roles, and I suggest using middleware for that.
Good thoughtful question, Abiodun. verifyJWT is in use at line 42 of the server.js in my example so it applies to all routes that come afterwards like the employees route. That said, you could remove it and apply it specifically to individual routes like I show with the verifyRoles middleware if you choose to do so. 🚀
Nothing is 100% secure in the frontend, but yes, if sending from the REST API to the client (browser) so the roles can be used, I'd send them inside the token.
this is awesome, answered so many questions i had before watching this, just one question i have tho, assuming i have a user with role of admin, and i want to secure it in the "app.use" area, but i also want to verify if user already logged in, and has the role as well, meaning i need to create 2 middlewares, is it a good approach if i create 2 functions for that in my auth controller, then in main.js file (main file in project), i'll import it at the top, then use something like app.use("/secured", verifyJWT, verifyAdmin) ? so even if user is indeed verified logged in, they also have to have the role admin
Applying app.use() will apply it to all routes that come after. Your middleware should not be created in your controller. I apply middleware to specific routes like you can see here: github.com/gitdagray/mongo_async_crud/blob/main/routes/api/employees.js ..this all comes before the controller. You can apply more than one middleware to a route.
Hi Dave it is a good idea with role codes! when it comes to verifying auth header, I prefer to destructure: const [bearer, token] = req.headers.authorization?.split(' '). Results in much cleaner code down the pipe.
Hi Dave, Thank you for providing very conceptual tutorial, please tell me one thing I will be greatly thankful to you because I am learning react and node just on a self-study basis. I created the schema with my cars inventory with status purchased When I sold the car how can we change the status of the car from purchased to sold, please guide me or any tutorial or study ref available then please provide me how to change the status of the product after sold our product from purchased to sold?
You are asking about updating data. Updates are part of a CRUD application. Create, Read, Update and Delete is what the CRUD acronym stands for. Follow the full playlist for this course to learn how to do all of these CRUD operations.
@@DaveGrayTeachesCode Thank you for your response, I am not asking updating data , I am asking to change the status of the product. Suppose I and doi g business of a car dealership, I purchased one car to sell. I insert data from my car with the status purchased .But when I sell that car then the status will be sold instead of purchased in my dashboard.
@@iramimran3117 Have a stauts property in your schema. The default could be purchased for example. Then created an updateCarDetails function in your backend that modifies any stored cars with whats provided by the frontend. Much like an update employee function in this course. In your dashboard have a toggle or a button that once pressed makes a call to your updateCarDetails function and sets the status to sold.
Hi Dave, thank you very much for this video, cool as always. I'm an intermediate developer and I've always struggled with scaling the backend. You seem to be a very experienced developer so I wanted to ask you here to create a series on scaling techniques. And to be clear, I mean for example when an app is supposed to have millions of users. Just as an instance, somewhere in this video, you mentioned that we might want to store the roles (and their codes) in the database, however, wouldn't that mean checking the database on every request only for the purpose of the authorization part? (I know this is just "one way"). Also keeping them in code has this downside that "DATA DOES NOT BELONG TO CODE, IT BELONGS TO DATABASE", but which way should a developer prefer if they know their application will gain a big number of users in a short period of time? What are the common methods that highly scaled applications use in order to increase their performance in case of such repetitious requests? I know these things are usually either very advanced or proprietary, but I'm sure there are at least some best practices and known methods in the world of scalability (say Redis, Sharding, HA clusters, Kubernetes, etc.), and I believe the world needs more great teachers like you on them 😎 Yes, no one knows everything, but please do share with us whatever experience you have in that regard too, it's greatly missing.
Thank you for the kind words 🙏 Much of my teaching focuses on beginners to intermediate, but for your questions, I suggest checking out @JackHerrington - Jack Herrington's channel. It is excellent and he has decades of experience: ua-cam.com/users/JackHerrington
@@DaveGrayTeachesCode Yes, I've subscribed to Jack Herrington and I have learned loads from him especially about Typescript and State Management. However, I only recently discovered your channel and I've found that you cover some vary useful and often overlooked skills that hardly anyone else bothers with such as best practise implementation of refresh tokens and accessibility friendly forms. Thank you for being here to cover the gaps in my knowledge 👍🏾
No need to overthink an example like this. Different organizations can organize their roles to their needs. I believe I do show one benefit of using an object lookup for the roles during this tutorial - using dot notation and not needing to type the roles which could lead to typos. All personal preference or organization preference though.
@@DaveGrayTeachesCode ah sorry, I stopped watching half way through because I loved the route structure so much I immediately started implementing it referencing the first half of your video but quickly was met with hours of debugging haha. I'll definitely finish the rest of it now I have everything working
I have an idea por a serie you can do. Why don't you build a social network nodejs api? maybe store photos with cloudinary. Teach us how you would set the role for the users, if you'd store comments nested in arrays or used by references... and so on. That could be fun. I haven't seen a serie like that here on youtube
Good question! You can encrypt whatever you wish before storing and then decrypt it when you retrieve it. I *think* I covered bcrypt and storing the encrypted password before this lesson, but maybe not... if not, it will be coming up in this series.
@@DaveGrayTeachesCode Thanks sir ,let me show us how an admin can create his account ,either he should manually create his account in database and put his roles there or in frontend ,we enable an option or checkbox or roles option ,like if you are user/admin then paste your roles etc ,and this registration data will be then store in the mongodb database...i am very confuse about that...
Good request, Usman. An admin panel for this would be a nice addition for user maintenance. Currently, you simply need to manually add an admin to the database as you do any other role besides "user".
i think there is an error, when i try to login i don't get a token when the verifyJWT function excute , i don't have a header that start with Bearer at that point , so i get an Unauthorized response, please help me
@@DaveGrayTeachesCode i think it's because my server send back a 401 unauthorized error instead of 403 like your's at the baseQueryWithReAuth() function, and that prevent the refresh route to execute, what should i do ? should i add 401 at the condition check of errors ?
@@DaveGrayTeachesCode i finally found the issue , it's when i use axios instead of the apiSlice, can't we integrate axios to the apiSlice can you do that please ?
In this tutorial, we'll compare *authorization* to authentication. Once we understand both concepts, we'll expand the authorization given to our JWT tokens by including user role and permissions info in the process. If you're just starting with Node.js & Express, I suggest going to the beginning of this *Node.js for Beginners* playlist here: ua-cam.com/play/PL0Zuz27SZ-6PFkIxaJ6Xx_X46avTM1aYw.html
sir permission based project please
@@shocchosolutions6275 here's a React series where I use the permissions created with this Node tutorial: ua-cam.com/video/oUZjO00NkhY/v-deo.html
Hi. How do i set authorization for a case where i need to verify if the user who's logged in is the author of a specific item?
Great tutorial and a seriously underrated channel! I'm learning on my own and have been having a really hard time piecing these backend concepts together - this helped a lot. There's a lot of frontend tutorials out there, but not as many backends. Keep up the great work! subbed and liked
Glad I could help! And thanks for the note. 🙏💯
Wowwwww!!! this series of node and express tutorials is amazinggggg!!!!! I went through the whole series and really learned a lot even though I have used express for a long time. Thanks Dave, pls keep going for the excellent content, this is the best node &express tutorial on UA-cam.
Thank you for the kind words, Daniel! 🙏
Thank you for another fascinating lesson.
A couple of notes:
(1) 26:44 - It is not shown on screen but maybe you should consider to make it clear with hard-subs (because it might be confused)
That in, the content of the Body tab is: {"id": 3, "firstname":"john", "lastname": "Doe"}
(...took me awhile to figure it up, and it might ease others, so..)
(2) 27:25 - Thank you for the clarification, but in this point people (such as myself) -
Might already got confused and spent some time to figure it out on their own,
So you might want to consider, again, to clear it up in the relevant (previous) video, with hard subs.
* If those are too difficult to produce now,
Then these clarifications might be helpful as notifications at the description
(..which is quite busy already as is, but.. ..yeah).
Thanks - your comments may help others. UA-cam does not let me edit / change videos that have already been posted. I could continue to add to the description but as you mentioned, it already has a lot. Many provide suggestions and I may use these when I cover the topic again. 🚀
Awesome video series!! I've tried many times to understand node in more detail together with JWT Authorization and Authentication and this is the best resource available by far! Looking forward to taking more of your courses once you have your platform up and running!!
Glad it was helpful!
What a brilliant teacher. Take love and massive respect sir❤
Thank you so much!
This is a very nice concept to apply access roles,
I used to use similar concept before (saving user roles upon login process),
everything worked nice until I encountered a case where a user was misbehaving and I needed to remove some roles, unfortunately there was no way to invalidate his access token and I had to wait for him to logout or for his session to get expired 🤦♂️😥
I really appreciate explaining the concept, this will make coding easier,
Thanks Dave,
Great story to share Ahmad. Trouble-users are another consideration for sure! Thanks once again for your thoughtful comments. 🙏💯
@@DaveGrayTeachesCode sometimes a lesson is learned the hard way 😎
Thanks once again for the great content 🚀
Awesome info. This tutorial and other ones you created provided all the answers I needed on how to integrate JWT into my project along with roles. I was cornfused before and now I'm less cornfused.
How do u automatically generate new access token from the server side with hit endpoint refresh token.. cos on d client once user is active d refresh token to generate new without re login.. pls
Brilliant video, well explained and very professional!
Thank you, Ben! 🙏🙏
It's a great one. Thanks a lot Gray
You're welcome!
You're amazing. Thank you for sharing all this information! I wish you all the best in life.
Thank you for the kind words, Omar! 🙏🙏
good idea with role codes! when it comes to verifying auth header, I prefer to destructure: const [bearer, token] = req.headers.authorization?.split(' '). Results in much cleaner code down the pipe.
That's a good approach! 💯🚀
@@DaveGrayTeachesCode I wonder how you configure a special role in this mix, which is owner - so a document can only be mutated/deleted by admin or owner
@@aram5642 on a per-document basis you would have to track the document owner and match it up, too. Otherwise, adding permissions for an admin only route to a delete endpoint should be much like the other restricted routes.
In the timeframe 09:48 you are obtaining the userroles from the founduser. But the userroles is also present in the decoded variable. can we assign the jwt userroles from founduser or decoded.userroles. both are fine?
Hey nice tutorials. I have a question. Why at 12:50 why need to modify request object and set user and user roles to it, when all this middleware does is check whether we have auth token?
Took time but Worth it!
Hi sir, After this video i hope you will create a video about OAuth2 with current source code. Thank sir. :3
Thanks for the request!
Helpful video thank you 😊 🙏
You're welcome! 💯
So good tutorial thank you
You're welcome, Sona! 🙏
If a bad user tried to hack our app by decoding his jwt and changing his userId and encoding it again and storing it in localstorage again, can he do it? Can't we detect that in the node server?
If I remember correctly, we are using jwt-decode middleware in this tutorial. (Reference: www.npmjs.com/package/jwt-decode) If a token is changed, it will be detected because they will not know the embedded secret key. You can also decode tokens at the following site and see how each part works: jwt.io/
Hi Dave! Great work, really enjoy your method of teaching and way of explaining everything. I consider myself more than a beginner but not advanced for sure, and I have found a lot of new information and new tips and tricks to take away from your lessons. I do have one question. I understand the process of passing the roles inside the JWT and validating them during the request process. However, what I don't quite understand, is why you use numbers associated to each role and not just level names (i.e. "admin" for Admin), I know you said that there are many constructs to role permissions, so maybe this is just one variation and there is no meaning behind it, but I was curious what your thoughts on it.
Thanks Robert! And great question - I think I only briefly mentioned it at best. And you are right that roles and permissions can be structured in many different ways. I've found they are often associated with codes or IDs. In this specific tutorial example, I briefly mentioned that a backend dev will not have control over how a frontend dev chooses to store the access token. While I believe an access token should only be kept in memory, others do put them in local storage or cookies that are not httpOnly. If someone got a JWT and decoded it (like you can at JWT.io), they can easily read the payload. I'd rather have a code or two in there instead of clearly stating this is an admin token for example. Just a bit of security through obscurity if the JWT is mishandled.
@@DaveGrayTeachesCode Thanks again! I had a feeling it was going to involve some bit of obscurity, but I wanted to make sure I didn't miss anything. This also allows you to know the roles without a database lookup for every API call. Nice! Again, great work, keep it up! I'm always looking for great content and something to learn, I'll be watching more and more of your channel.
@@robertmoore7158 thanks again for the kind words! Glad I can help.
Love it sir .. ❤️
Hi Dave , your explanations are just Perfect ,
Please, any chance to ses PHP and symfony series in a near futur please ?
Thank you for your JS long video , definitly super great !
Great suggestion! There is a chance I could do that topic in the future. 💯
@@DaveGrayTeachesCode waw thank you Dave ! Wish you all the best !😏
i think that you should prepare some slides about theory of each lecture, for example authentication , but anyway your nodejs express course is awesome and amazing , i hope that in the future you can make advanced course about nodejs .Tks very much !!!
You're welcome!
If I were to need to update the user for an API post request -- for example, the user clicks a button, and something is changed on their user account -- would it make sense to just use the refresh token to lookup the user in the database like you demonstrate with the login and refresh routes? I'd prefer to use the user ID directly, but I imagine passing it through one of the tokens would be a security risk. Thanks!
Hello Mr. Dave can you help me how should we implement dynamic roles and permission base Authorization through node js... just like django Crm
Subbed. Thank you
You're welcome!
if i manually update the json file in Compass with the role i hope it works the same way than having a data file in my directory
Hi Dave thank you so much, but i have a question how i can handling expired refresh token ?
We should let a refresh token expire. Having a user log back in every now and then is a good idea.
hey dave may i know why have you used refreshTokenController in jwt authentication, i could not get the idea of creating another refresh route and generation the new access token
Ds is d same problem I have, please did
u figure it out?? I thought we could implement it as middleware directly
it's perfect content. I sent you message from twitter. I'm one of flutter and nodejs developer and I want to introduce you in my country (turkey) if we can make video together for 10 minutes for beginners I will be happy to translate for turkish franch and arabic! it's pleasure discovering your channel
Thank you Abdullah. I'll check my messages, and I appreciate you reaching out.
@@DaveGrayTeachesCode okey thank you I'm waiting for your answer 👩💻😊💯
Can you implement whole authentication and Role manage system in front end in react with RTK query it will be really helpful for fullstack developer 😍
I recently did that in my MERN Stack course here: ua-cam.com/video/CvCiNeLnZ00/v-deo.html
Very very niiiiice!
Hello Dave. I'm sorry for another question:
we check if there is access token in request and that it hasn't expired
if access token has expired we need to refresh token and if cookie jwt is stored in database it will be refreshed
but how it would work from frontend side?
we have access token inside store
we send GET request to secure route - it sends back 403 (token has expired)
so we need to make one more request to /REFRESH (checkes cookie jwt and gives back new access)
then rewrite our store token
and then make this get request again?
so if we work with redux we need middleware function which will implement at max 3-4 extra requests under the hood of every CRUD requests?
No, 3 or 4 extra requests are not necessary. You can see how it is implemented with Redux here: ua-cam.com/video/-JJFQ9bkUbo/v-deo.html ...for more on the frontend and using this strategy, I have a full React Auth playlist here: ua-cam.com/play/PL0Zuz27SZ-6PRCpm9clX0WiBEMB70FWwd.html
@@DaveGrayTeachesCode Thank you Dave. Yeah, have started your MERN course. I try to watch and repeat your every tutorial, they are extra helpful. You are the best!
Thanks, Dave, great video. Quick question... Is there any available service to which we can delegate the RBAC management to? For instance, if Cognito is taking care of the Authentication, do you know if there is any service for the Authorization part?
Also what solution do you recommend for partial access levels? For instance, a user has Read access but only on his own posts? do these need to handle at the controller level or can we come up with a middleware that can filter response?
Thanks - You seem to be asking about Amazon services. It seems Amazon Cognito can handle RBAC: docs.aws.amazon.com/cognito/latest/developerguide/role-based-access-control.html
Many different solutions are possible for partial access. I would consider different levels of roles for this.
Yo da one, Dave!
Thanks! 🚀
rolesArray coming undefined. pls help someone
good 1.
would love to have this emplementation with mssql DB too ..
thanx
I can help with that. That's the stack I have at work now. Good future tutorial idea💡
@@DaveGrayTeachesCode
great,
will await
good stuff!
Glad you liked it!
In verifyRoles.js "Some" array method could have been used in place of chaining "map" and "find" when checking if rolesArray and req.roles contains the same elements.
Agreed - and not the first to mention this. It works as is, but feel free to change your code.
Very rich playlist. However, I don't see the usecase for the accesstoken as response to the /login endpoint. First, because you advised that we should only store in memory, so we can't store in a state or context in the frontend that we can use to say access /employees endpoint later on. So maybe everytime we need to access the /employees endpoint, we first call /refresh and get an access token then call the /employees endpoint. I'd like anyone to point out a usecase for the accesstoken as response to the /login endpoint.
Hello! I have done this tutorial two times and also tried the testing with thunder client with the finished source code and am receiving the following error:
Error: secretOrPrivateKey must have a value
at Object.module.exports [as sign] (.../node_modules/jsonwebtoken/sign.js:107:20)
The line of code in the /sign.js stated:
if (!secretOrPrivateKey && options.algorithm !== 'none') {
return failure(new Error('secretOrPrivateKey must have a value'));
}
I believe from looking online this is due to missing the contents of the .env file. Are you able to share what those would be? I've gone back through all the videos and am having a hard time finding where that was created and the variables inside it.
Thank you!
The .env file just contains a secret variable value that you do not want to share in Github or other public resource. Confirm you have installed the dependency and that you have the dotenv required in the server file as shown in my source code. Any time you reference a variable found in the .env file, you reference it with process.env.VARIABLE_NAME (where you replace VARIABLE_NAME with whatever the actual name of your variable is). Otherwise, as you mentioned, going back through the code and tutorial can often uncover a small difference that creates an error when you follow along.
much thanks!!!
You bet!
mr dave, hi, what about an upload & resize image tutorials, and what technology do you suggest for notification system , all in react of cours
I have a Node.js upload video here: ua-cam.com/video/4pmkQjsKJ-U/v-deo.html Notifications can be handled in any stack you choose. I would likely use MERN.
@@DaveGrayTeachesCode yes me to but i saw people use socket or stream what's your opinion sir
@@digitalpartner7598 I do not have a preference. You could go with what you already know or what you want to learn more about.
Should i create different controllers for different roles?, eg: in some cases i need to use populate to get certain references within the document based on the role
No. Controllers are not based on roles. You usually route to a specific controller. You can control access to the route with roles, and I suggest using middleware for that.
@@DaveGrayTeachesCode Thanks
Are we not supposed to add the verifyJwt before verifyRoles to the route?
Good thoughtful question, Abiodun. verifyJWT is in use at line 42 of the server.js in my example so it applies to all routes that come afterwards like the employees route. That said, you could remove it and apply it specifically to individual routes like I show with the verifyRoles middleware if you choose to do so. 🚀
Is security putting roles in JWT payload? like admin, customer, etc.
Nothing is 100% secure in the frontend, but yes, if sending from the REST API to the client (browser) so the roles can be used, I'd send them inside the token.
this is awesome, answered so many questions i had before watching this,
just one question i have tho,
assuming i have a user with role of admin, and i want to secure it in the "app.use" area,
but i also want to verify if user already logged in, and has the role as well, meaning i need to create 2 middlewares,
is it a good approach if i create 2 functions for that in my auth controller,
then in main.js file (main file in project), i'll import it at the top,
then use something like app.use("/secured", verifyJWT, verifyAdmin) ?
so even if user is indeed verified logged in, they also have to have the role admin
Applying app.use() will apply it to all routes that come after. Your middleware should not be created in your controller. I apply middleware to specific routes like you can see here: github.com/gitdagray/mongo_async_crud/blob/main/routes/api/employees.js ..this all comes before the controller. You can apply more than one middleware to a route.
@@DaveGrayTeachesCode got it, i managed to work around it the i wanted it to be, thanks
This is the good way to provide roles code in open file is it secure ?
Hi Dave it is a good idea with role codes! when it comes to verifying auth header, I prefer to destructure: const [bearer, token] = req.headers.authorization?.split(' '). Results in much cleaner code down the pipe.
Good idea!
Hi Dave, Thank you for providing very conceptual tutorial, please tell me one thing I will be greatly thankful to you because I am learning react and node just on a self-study basis. I created the schema with my cars inventory with status purchased When I sold the car how can we change the status of the car from purchased to sold, please guide me or any tutorial or study ref available then please provide me how to change the status of the product after sold our product from purchased to sold?
You are asking about updating data. Updates are part of a CRUD application. Create, Read, Update and Delete is what the CRUD acronym stands for. Follow the full playlist for this course to learn how to do all of these CRUD operations.
@@DaveGrayTeachesCode Thank you for your response, I am not asking updating data , I am asking to change the status of the product. Suppose I and doi g business of a car dealership, I purchased one car to sell. I insert data from my car with the status purchased .But when I sell that car then the status will be sold instead of purchased in my dashboard.
@@iramimran3117 Have a stauts property in your schema. The default could be purchased for example. Then created an updateCarDetails function in your backend that modifies any stored cars with whats provided by the frontend. Much like an update employee function in this course. In your dashboard have a toggle or a button that once pressed makes a call to your updateCarDetails function and sets the status to sold.
Wow amazing
Thank you! 🙏
Hi Dave, thank you very much for this video, cool as always. I'm an intermediate developer and I've always struggled with scaling the backend. You seem to be a very experienced developer so I wanted to ask you here to create a series on scaling techniques. And to be clear, I mean for example when an app is supposed to have millions of users.
Just as an instance, somewhere in this video, you mentioned that we might want to store the roles (and their codes) in the database, however, wouldn't that mean checking the database on every request only for the purpose of the authorization part? (I know this is just "one way"). Also keeping them in code has this downside that "DATA DOES NOT BELONG TO CODE, IT BELONGS TO DATABASE", but which way should a developer prefer if they know their application will gain a big number of users in a short period of time? What are the common methods that highly scaled applications use in order to increase their performance in case of such repetitious requests? I know these things are usually either very advanced or proprietary, but I'm sure there are at least some best practices and known methods in the world of scalability (say Redis, Sharding, HA clusters, Kubernetes, etc.), and I believe the world needs more great teachers like you on them 😎 Yes, no one knows everything, but please do share with us whatever experience you have in that regard too, it's greatly missing.
Thank you for the kind words 🙏 Much of my teaching focuses on beginners to intermediate, but for your questions, I suggest checking out @JackHerrington - Jack Herrington's channel. It is excellent and he has decades of experience: ua-cam.com/users/JackHerrington
@@DaveGrayTeachesCode Yes, I've subscribed to Jack Herrington and I have learned loads from him especially about Typescript and State Management. However, I only recently discovered your channel and I've found that you cover some vary useful and often overlooked skills that hardly anyone else bothers with such as best practise implementation of refresh tokens and accessibility friendly forms. Thank you for being here to cover the gaps in my knowledge 👍🏾
@@stevereid636 You're welcome! 🙏
Hi Dave, would you consider making a longer more detailed Node/Express tutorial for Udemy? I will definitely buy it if you do. Thank you!
I may make a more detailed premium course for this at some point. I will not use Udemy, but I'm looking at creating my own platform.
@@DaveGrayTeachesCode Thank you! Let us know when you do as I am sure I am not the only one who will be waiting for it.
does `secure: true` works with Postman?
Yes, it does.
But why not make the roles just an array of strings how do they benefit from having additional number id's attached to them
No need to overthink an example like this. Different organizations can organize their roles to their needs. I believe I do show one benefit of using an object lookup for the roles during this tutorial - using dot notation and not needing to type the roles which could lead to typos. All personal preference or organization preference though.
@@DaveGrayTeachesCode ah sorry, I stopped watching half way through because I loved the route structure so much I immediately started implementing it referencing the first half of your video but quickly was met with hours of debugging haha. I'll definitely finish the rest of it now I have everything working
I have an idea por a serie you can do. Why don't you build a social network nodejs api? maybe store photos with cloudinary. Teach us how you would set the role for the users, if you'd store comments nested in arrays or used by references... and so on. That could be fun. I haven't seen a serie like that here on youtube
Thanks for the suggestion! 💯
I think its a bad idea to make the roles collection a part of jwt payload.
you could've used roles.some() instead of chaining map & find
Yes, often times there are several ways to achieve the same goal. Good suggestion! 💯
Dear Dave, just out of curiosity.. wouldn’t it be better just “store” encrypted info ?
Good question! You can encrypt whatever you wish before storing and then decrypt it when you retrieve it. I *think* I covered bcrypt and storing the encrypted password before this lesson, but maybe not... if not, it will be coming up in this series.
I dont understand how to send these roles during user registration process in front end ,can anyone guide me about that ???
When you get to the next video chapter, I show how to create a JWT and send the roles in the token.
@@DaveGrayTeachesCode Thanks sir ,let me show us how an admin can create his account ,either he should manually create his account in database and put his roles there or in frontend ,we enable an option or checkbox or roles option ,like if you are user/admin then paste your roles etc ,and this registration data will be then store in the mongodb database...i am very confuse about that...
Good request, Usman. An admin panel for this would be a nice addition for user maintenance. Currently, you simply need to manually add an admin to the database as you do any other role besides "user".
awesome
Thanks! 🙏
This returns an error
TypeError: req.roles.map is not a function
If .map is not a function, that means you did not create a roles array where needed. I suggest you go back over how the roles are created.
2001, 1984, 5150 - If those aren't random ... I recognise at least 3 common interests!
You are right! 💯🚀
то что нужно!
Glad to hear that! 💯
🚀
i think there is an error, when i try to login i don't get a token when the verifyJWT function excute , i don't have a header that start with Bearer at that point , so i get an Unauthorized response, please help me
I suggest looking at my source code which is available at the course resources link in the description. Compare to yours for differences.
@@DaveGrayTeachesCode ok
@@DaveGrayTeachesCode i think it's because my server send back a 401 unauthorized error instead of 403 like your's at the baseQueryWithReAuth() function, and that prevent the refresh route to execute, what should i do ? should i add 401 at the condition check of errors ?
@@DaveGrayTeachesCode i finally found the issue , it's when i use axios instead of the apiSlice, can't we integrate axios to the apiSlice can you do that please ?
The docs show how to integrate Axios with your baseQuery: redux-toolkit.js.org/rtk-query/usage/customizing-queries#axios-basequery
Jet like ::before
Next time I expect to get GraphQL instead of REST
I'm finishing this series first which is about bringing the pieces of the MERN stack together, but I appreciate your request for GraphQL.
@@DaveGrayTeachesCode Thank you very much!
5150 role must be at least High-Gain-King. "Admin" isn't cool enough