NestJs RBAC - Role Based Authorization Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
you need to know rbac it stands for role-based Access Control it's one of the three main variants of access control and is basically defines who can do what in your application based on its assigned roles so whether you're building an Enterprise focused application or just a tiny SAS knowing Access Control will greatly simplify your application and improve your security in this video I'm going to show you how to use rbac by managing a fictional organization called e-corp that has three distinct roles by the end of this video you'll be able to manage access control like a pro so if you want to keep your application secure and make your life easier stick around to learn about rbac and don't forget to hit that subscribe button so you never miss a video did you know that over 80 of data breaches are caused by stolen or weak credentials that's why rbac or role-based access control is an amazing tool to secure your application at its core RBC allows you to assign roles to your users and control what every role can or cannot do for example you might want to assign an admin role to a user that needs to manage other users while limiting their rights to delete some critical data in the application or you might assign a guest role to a user that is able to view certain parts of the application while limiting their ability to edit any data rbec is one of the three main variants of Access Control the other two as mentioned by the National Institute of Standards and technology is ibac which leads to access control lists and ABAC we which stands for attribute based Access Control in terms of complexity RBC stands right in the middle between ibsc and ABAC for instance Access Control lists are commonly used to protect individual resources a bit like what we use in S3 buckets while ABAC are like rbec on steroids where you don't assign a user to a specific role with permissions but where you assign permissions to the users based on their intrinsic properties for instance you can use attribute-based Access Control to restrict when your employees can log in into your application based on their time zone where they are in this video we are going to focus exclusively on rbec but let me know in the comments if you want me to do another video on other methods of authorization so now let's jump to the code the code is as always in the description of the video below so the project itself is made of react and Nest GS by the way if you are unfamiliar with an SGS I have a course that will help you to get up to speed in no time Link in the description below so if you want to support the channel check it out so the project is a pnpm mono Reaper so we have kind of two projects that are shared inside the same GitHub repository so we have an API here and we have a react application so the react application is made with vanilla react and Veet and as I've said API is made with Nest GS so to be able to use the application you need to start the API and the react app at the same time this can be done easily by starting two terminals so here we go to start the API we can use pnpm filter so here you indicate the app that you want to use here we want to use the API app and we want to run the script start.dev which come from the package that Json of that specific project so the backend is now started and all good and now we can start the um react so same filter react Dev and it's going to run the script Dev inside the react folder right so our react server is started on localhost 5173 so the product is using Prisma the database I'm using is SQL live just because it's easier to work with it's just a file we have some migrations here and we have a Prisma schema so in the Prisma schema it's a very basic application we have a user model and we have a department model so pretty much the user can be part of different departments and we have a many-to-manual relationship between the departments and users and this is done by the model user Department link so the link will indicate which role the user has user admin or manager and what kind of title it has in the specific departments so another thing you might notice is the seed script so the seed script will generate the data the fake data and I'm using Faker JS for that the fake that is going to be generated just to so we can populate the the application so we have a helper function here that creates a user basically every user has the same password so it has been kind of hacked and what I'm doing in the main script of that seat file is that I first clean the database so you can run the the seed script many times and everything is going to be fine we so we first create all the Departments and it's done based on the object here so here we create the admin and there will be only one and as in Mr Robot we have Terry called you who is the admin and basically and basically the admin will be able to assign roles to users so he'll be able to promote a user to manager or demote a manager to user so they all have again the same password and you can go into more details here that's not the point I just want to show how pretty much you can use rbec in that specific context we also create a manager Tyrell Relic who will be manager of ecoin department and we create 100 users who will be kind of randomly assigned to different departments and that's it this script the seed script is run through the package that Json here so it goes inside the Prisma namespace and if I want to run the seat I just do a npx Prisma DBC inside that specific API folder so it will regenerate the seed but for now I won't do that because I already have all the users generated I will also go a bit through the kind of basic architecture of the application so we have the main.ts we're using sessions so Express sessions to handle login State and logout actually we also have a logout functionality and we have course enabled simply because the react is going to run on another Port of the localhost and we need to tell the API that hey we actually want to allow the react application to make API calls to to the back end and we also want to pass the credentials so meaning the set cookie credentials in the headers automatically apart from that nothing really fancy we have some Global pipes for transformation and that's about it so in the app module we just create all those modules that we're using here's the access control module that I'm going to come back just in a moment and you notice that we have a session card and a AC guard and the AC guard Access Control guard is actually part of that kind of Access Control library that I chose to use for this specific project that again I'm going to introduce in a moment and just be patient we have the odd module Prisma module employee data module and user models so the kind of main routes module are those three so this is just a helper module for for handling Prisma so inside the odd module and I chose to put all everything regarding authorization authentication inside that module we have the rbec policy we have a strategy local strategy I'm not really a fan of like logging in the user that way because a strategy for me is better used for authorization versus authentication and I think passport is kind of mixing the two but and or if you are using local strategy then you are kind of protecting your kind of API with basic notification it doesn't really make a lot of sense for me but anyway I chose to implement buy the book so we have a log again endpoint here it's using the strategy local and basically the local strategy is handling the the authentication so it fetches the users it validates the user if it doesn't find the user in the database it throws an error and by the way you notice that there's no sign up functionality just login functionality and it's very naively checks if the user is admin or manager and then fills pretty much those kind of data inside the request.user object so that that is available in the requested user object just for project at that endpoint so and what we do once the login has happened was once the authentication has completed we assign those kind of values from the requested user to this session and then um and then we just return a status okay code and we return a status okay we return a Json just so we don't return a text or no because on the front if you're using a fetch API you like it doesn't return a Json you cannot do like response Json into do response tags and I didn't want to handle those kind of use cases so I always try to kind of stay consistent and return a a Json here so that's about it we also have a log out uh endpoint and all it does is it just destroys the session that's that's about it and return say two of four code and we also kind of return the the code here as a Json okay so let's quickly look at the guards so I have a session guard once user has logged in he will send the cookie the session ID in the cookie and that guard is going to be able to extract the session data based on the session ID that the user sends and save it in a request.user why well is because the authentication Access Control library that we're using needs that and again we're going to come back to that in a moment and we have a roles card so Rose guard I said that it's a very simplistic kind of implementation of rbec technically how it works is that let's say you have some employee data here right let's say that you have this endpoint that needs to be protected that needs to be only accessible by let's say admins right well one way is to assign a metadata and say hey this is for admins right and if you have another endpoint that needs to be assigned to admin and manager you say hey this is for roles of admin and manager the main problem is that as the application grow you can have like lots of roles you can have 20 30 roles and you'll be kind of forced to kind of have those link those big arrays of roles here so let me show you what that could be so for instance roles and you can have oh this should be accessible for admin this should be accessible for manager they should be accessible for like I don't know manager two so instead of doing that instead of saying which roles can call those endpoints what we do is that we say which permissions the roles should have to access that endpoints and since a lot of those roles share the same permissions we can just say hey actually this this endpoint should be accessible for people who can I don't know read the managed data manage employee data and then it becomes more more easy to to handle but of course if your application is very very small and you just need to restrict literally some endpoints to be used by the admins you can use something like that and that guard pretty much just checks if the required rules are set in metadata match the roles in the session that user array and that's all I kind of wanted to say and let's get back to that rbec that I talked about so here in this example I'm using access control it's a kind of RBC slash ABC Library that I found really uh really nice and the reason is because there's not a lot of options and let me show you so first of all let me start by saying that it's very hard to find a good library on RBC very surprisingly a lot of the libraries are either very old or don't have a typescript support it's like it's actually quite crazy so the first Library I kind of came across was rbac and rbec look like a very good one but it didn't have typescript supported which is a deal breaker for me so I had to look for something else then I found another Library called Nash GS rbac which looks very good as well but for some reason the documentation was on unclear for me the examples were not very clear and it seemed to be also a old library so I kind of didn't want to go that way and I've ended up by finding access control which I kind of really liked and their philosophy is kinda built on the idea of merging the tool RBC and absc based on the uh recent nist papers so basically what it means is that you define the roles like that and you grant them permissions so the next thing I have to look for was a library that managed that for nashes otherwise I could have implemented that by myself but it's always better to have a library and it happened that it exists it's called Nest access control so that's the library I used very grateful for the creator of that Library a very easy to uh to use very well documented so you basically are in the same way create roles like that and you grant them permission and you can extend so there's inheritance so you can say hey the admin should inherit from the manager but it should not do certain actions so this is the library I ended up by using so let's check our RBC policy here what I did here is that I say hey we have users that have the authorization to read its own kind of employee data although I didn't really Implement that kind of endpoint because the it's kind of personal employee data are read by me and me endpoint already knows which user it is calling in so it will not allow to uh to have an argument or to get something that you don't control you don't own so that role is a bit useless here but basically we have three roles users managers admin the manager extends from users and the admin extend from manager and for instance the manager can read manage the employees data and it can read employee details and the admin can it's extending pretty much from the manager it can also read employee data update employee data and delete employee data but it cannot read manage employee data which the manager can read and it makes sense because the endpoint to read manage employee data should concern only the managers not the admins simply because I don't have a necessary logic in it so it's a very simple way to kind of deny the ability to call a certain endpoint if you don't have a certain role so if we go back to the employee data and this is kind of the core of the of the application we have the controllers here here and here's my preacher complaining we can clean that here and basically here we have a couple of endpoints and we see that we used used rows that comes from Nest Access Control it's just the decorator that will allow to tell which resource it is and which action can be done by this resource and the possessions pretty much any of our own here in this case is going to be any for everything so that's pretty much an end point for admins because employee data the permission to read employee data is only owned by admins here CN point for managers because this permission specifically is only granted to to managers you have employee details employee data so you got the idea right so basically we protect our endpoints we protect our application that way traditionally you don't kind of you don't have to use resource based control you can go in the logic you can go in your service and kind of write the logic that way if it's very simple that's fine so for instance you can first fetch the user by its user ID that is calling the the the endpoint and verify if it has for that specific endpoint the uh the necessary permissions the main problem with that is that well it creates all the spaghetti code a lot of like repeatable code because on every endpoint for instance you go here or here we first need to get the user ID so it will be something like user ID the user that is calling the endpoint right we need to load the user and then we need to check the permissions and that should be kind of done for every endpoint to avoid that and to to allow to have a more kind of secure application and that way you don't make all the possible mistakes that you could make in those kind of use cases we just use rbec so here we know that this function is only to be called by um who can call that by the manager or the uh the admin but not the user so if the user will try to call it he will get a 40 free for a free error so that's kind of the the gist of it so now let's go back to the UI and run the the logic so the UI is here and we have a signing route we need to enter the credentials here I'm going to enter the credentials of well let's say of a manager and I can go for that in the Prisma seat delete everything that is not relevant here and the email that we can log in with a spiral but Relic at ecorp.com password is that and here we go we have the title Relic UI he can see his employees that he manages because Tyrell wellick is the manager of the ecoin department and he only sees ecoin employees and that's kind of what the RBC policy defines now he doesn't he cannot do anything else so that's a very simple application but we can now log out and we can log in as the other guy the CEO the derby Terry Colby at ecorp.com and Terry Colby he will be able to see more information first of all if we go in the profile section he'll be able to see all the Departments that he is kind of part of and that is enforced by the many-to-many relationship that we have in the in the model so we see that he is admin of all those departments and because his admin of all those departments he can actually have a lot of Rights so he can promote users to another role so this is a very kind of simple uh implementation of rbec so the rbec policy here is not stored in a database is stored in the code so all the roles here are predefined in the code the access control Library allows you to store all those roles in a in a database but I didn't go that way because that would make the example very very heavy because you would need to create all the resting points to modify the the permissions you would need to create the UI so now that it's possible and in some cases you will have to do that it will always depends of your application if you're building something small where you just want to restrict uh the access to your endpoints to certain roles that are predefined for like small SAS or something like that that would do but if you want to have something more complex Enterprise Focus where you can assign custom roles assign custom permissions there you might use a database to store all those roles however if you're really doing something really complex where people can assign custom permissions it's in that case it's better to go ahead and use a ABC which will be much more flexible and granular than rbac so if we go back to our UI we see that we have managers and I just outline them in yellow so you see end users so if you so if you click on edit button for instance this guy let's see this guy this guy is a front-end developer at Bank of in network so I can click on edit and I can promote him to a manager and the one that is done he is a manager and if you want you can log in to the application as that specific user and all of them has the same password remember and you will see that he'll be able to manage kind of he will be able to see information of other users in in that depend on him because he's now measure and the same way if I want as a manager sorry as an admin I can demote him uh to to the role of user and now he's user let's actually go ahead and log in as a Ralph 13 here um here we go we can log out and and you see that as a user as a normal user you don't have access to anything specifically you just have access to your own profile data which is kind of unprotected so it's the endpoint slash me in the user's um controller so yeah the anything can access so here we don't need to kind of to protect that endpoint by a resource based access but if you try to call anything else that is not uh that is protected by the RBC policy you will not be able to to get a good response so now let's check it out Terry Colby e-corp.com foreign and let's promote that guy now to the manager here we go and login as that guy let me just copy that email because I already forgot the email here we go and now we see that this guy is a manager right of that department and he has access to the data of all the users that are in the same Department well that's it for our Deep dive into role-based access control I hope you found this video helpful and informative if you have any questions or comments on rbec or if you'd like to see more of the videos on specific topics please let me know in the comment section below and don't forget to hit that like button and subscribe to my channel to see more great content thanks for watching and see you in the next video
Info
Channel: Code with Vlad
Views: 16,076
Rating: undefined out of 5
Keywords: nestjs rbac, nestjs rbac tutorial, rbac vs abac, nestjs access control, nestjs role based authorization, nestjs rbac example, attribute-based access control, rbac access control, nestjs roles and permissions
Id: Um9wyVaB5Iw
Channel Id: undefined
Length: 24min 35sec (1475 seconds)
Published: Wed Mar 01 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.