NestJS Role Based Authorization | RBAC

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we'll implement role-based authorization and it continues off the previous video where we've used nsjs and postgres to implement authentication so we made the ability and the endpoints to register a user hash their password and store it in the database and there's also a type or a role corresponding to that user and by default it auto-generated to a user now i've created this second user here and i've made the role and admin type so currently i'm logged in as the user john hotmail.com so let's just go through the steps again you generate the token by hitting the endpoint based on that credentials you copy and paste that token as a bearer token into the api endpoint that we're protecting and then when you send it you get the 403 forbidden resource so it guards that resource for us because we're not actually eligible to make that or authorize to make that request however if i sign into john 2 and then i copy that token for the admin user and then i go ahead and try and make the request now and if i just change the body to 24 we do indeed get back the response object and it's created so let's just go ahead and check that in the user table so i'll view all rows there oh sorry the feed post table and right at the bottom here for the second user i've got the body with 24 there so we can see that that request did work and if we're just to look at the code ahead of time just to see what we're working towards in this video in addition to the jwt guard that we've set here we've set the auth guard for the rolls guard and then we've put this second decorator for extra metadata that this rose guard uses based on the type of role that they are that we're trying to protect for so in this case we are saying that you have to be an admin to be able to make a request and otherwise it will fail so let's go ahead and get started so returning to our folder structure we'll just cd from the root directory into our api and from here this is where we're going to want to generate a guard using the scli and also a decorator so i'm going to do this before i start running the server so you can use nest g d for decorator now if we take a look at our folder structure i got this auth folder here where i've been doing the auth related stuff so i'm going to generate the decorator i.e the metadata or the at symbol above the request so we can have our own custom decorator so in a decorators folder i'm going to have a decorator called rolls and like always i want the folder structure to be in a flattened out version so there's no nested folders and no test files so we've got this decorator here and the second thing i'm going to generate is the guard so nest gu and in the auth folder in the guards folder we're going to have roles i'll just add these extra flags on again so as we've done in the previous video we've set up the jwt guard and implemented the jwt strategy so you need to have a valid jwt token as the end point um to guard against an endpoint but now we're going to add the authorization on top of that so even if you have a token you need to be a particular type of user so i'm going to start off here in the models and in the models actually i've implemented this in a previous video because i've set up the table but just to recap i've set up a enum that i've exported here and there's going to be a user a premium user and an admin and they correspond to the lowercase string and in the user entity there is actually a relation to this well there's a column for that enum for that role and that's what we've seen in the postgres database when we're looking at the particular user and by default it's making it as the user so if you want to make an admin you will just have to change that in the database so since we've got the model or the enum set up for us we can go ahead and take a look at the decorator that we've just created so in this roles dot decorator we just want to make a couple of adjustments here the first thing we want to do is we want to export as a constant so we'll make it all up a case the roles key and this more or less is just refactoring this part here [Music] out like that because we're going to reuse this variable in another location so that means we can use this roles key variable here where we're setting metadata and then we instead of calling this args we can call this roles and this is going to be of the type role or the array of roles because it's going to consider all the roles because you can pass in more than one role in the um guard so before we've seen that we had the at rolls which is at rolls is the name of this um variable here that we're exporting so this is the decorator name or the metadata that we're adding with that decorator and then the metadata where decorating is based on these roles and it's going to be so use the spread operator because we could have a number of roles here in an array so we could pass in we won't maybe want the admin and a premium user to see a certain feature but we don't want a regular user to see a certain feature and then if we pass those both in then we'll get an array of rollback now it could be that we get none or one but we still need to account for the fact that we may want to be using multiple things so that's our decorator now what i'll add now is i'll add basically with that decorator we can see in our feed controller so we've seen we've used this jwt guard here but what we want to do is now we want to use the roles decorator that we just created so we can do that and we to use a decorator we use this at symbol like before and the type that we want to pass in here is based on our role enum so in our first instance we would want to get the role we want to protect this route such that only admins can view this so that means we need to control period and import this so we've got roll from the models and i might just move the imports around slightly so but to use this now by this self this is basically doing nothing because it's not actually guarding anything we're just we've used this decorator and we've provided a little bit of metadata to this particular route here but nothing's happening based on that so what we need to do and this isn't created yet but preemptively i'm going to put this rose guard in here and start to work on that actually we i think we did create it but we haven't implemented the functionality that we need for that so if we open up the guard in the auth section we see we have this newly created roll guards now it is important that you if it's not already in the module to add it to the module and in our case it isn't so it's always good to check i find that sometimes the cli does add things sometimes it doesn't so it's always good just to spend a few seconds just to check and import that and with that as we've added as a provider so it's available in our all sections so we're able to use it so we can work on the logic in all roles guard and this is the main meat of the logic that we're implementing here so basically by default when you have a guard generated by the cli it extends can activate and if you're familiar with angular it's a very similar concept it the class it extends it requires you to um or the interface it requires you to use this can activate method otherwise if you comment this out you'll get an error on the rolls guard there so basically what this does is it needs to return some sort of boolean so that could be a promise boolean or an observable boolean and based on whether it says true or false that's what allows it to pass through so if we are using this roles guard and we say okay they made it through the roles guard that means it's returned true for us and then the post request has been made but if they don't have the valid credentials we'd want to protect against this and say false and then it won't even actually make it into this post request at all so one thing we'll need though is we'll need to because we are using our own custom decorator here we need to interact with this particular um [Music] decorator and get the decorator information and to do that next js has a service that's built in for us that allows us to get that information so if we just make a constructor here and then we inject the reflector that's what they call it then we'll be able to use that um and to be able to do something with that ie protect our route so of course we need to import this and this comes from sjs core i believe so what we want to do is we want to say we want to get the required roles that we need here so in this case what's being injected in this roles here is the role admin so that's the required authorization that we need to be able to make the request so we can just have something here called required roles and to access the metadata on that particular class on that function um sorry that end point that we're using here we need to call that reflector service and there's a method called get all and override and this takes a type of the type that you could put in here so you could have roll admin but you could also have role dot user or role dot premium let's say and if we um consider all those types that could be in we can say okay we need the role type and it's going to be an array of different role types and of course we're going to need to import that so in the arguments what it takes and why i've exported this roles key here is it needs this roles key name um so we can just go ahead and copy that because that's the data that we're setting so to get that metadata that we're setting we need to access it so we can access it through that same way we've set it so we accessing through this get method and as a second argument it takes it's going to need to know where it's looking basically so the class that it needs it needs to be looking at this feed controller class and it also needs to be looking at this particular endpoint so it's looking at this create method so it's looking anywhere in this feed controller class and it's looking for this create method in particular that's where we have our guard set and our roles for that rose guard there in the decorator and the metadata so this is where the context comes in hand so this context and that's coming from sjs as well from the execution context this provides context about uh the particular location that's calling it so it will make an end point we'll send a request to this such api slash feed and the context is needed so we need to know the controller and the method used by that controller in our guard so we're able to access the metadata from the uh decorators that we created in our guard and then we need some context um that pretty much suggest what method we're using and what area so with that said we can use the context get handler method and we can pass that in and we can also pass in our get class and it should be an x and of course this method is happening inside the can activate so it can activate sort of like a life cycle method in the sense that when you call the rolls guard which is called from just having this rolls decorator here and the rolls guard being used essentially this can activate method is just called basically similar to how constructors just called when the class is instantiated now we will need to get the roles key in from our decorator where we exported it and we're just getting an error here because we're not returning anything so let's just return something um but basically now that we have made we've passed in the role that we require from the user to be signed in as or authorized as for the roles guard and we've used the reflector to get that metadata and um context information about the class where it came from and what's called so the handling class we can say okay now if there are no required roles i.e you have the rose guard on but there's no roles here it's implied that it'll just make it through and then having that rose guard there's basically redundant so whenever you're using the roles guard you basically want to have some metadata associated with which role you want to have so if for whatever reason there is no required roles it's sort of implied that you know you've been looking through your code and then you've seen there's some roles and then you sort of delete it but then you might have accidentally left the roles guard there um in that case it's sort of assumed that you've allowed access or authorization to that endpoint so that means we're going to return true ie it passes through the can activate method and it will make it into this post request um what we can do is we can say and once again we can use the context so on the context and there's a method here called switch to http and it switched the context to http so we'll see what that means essentially what we want to do is we want to call this method called get request and that means for our request it's going to get like an object of information basically so what i want to do is we've already seen that we have for our um our requests that we because we've set up authentication in the previous video that the user is associated with the request so we can actually use object destructuring here and we can get the user from the request because when you log in you get the the token and then you put that in your headers and based on that you have information to the author basically or the user so you have their id and other details in particular their role so if you have that user and this should be a method here actually so based from the request we can use object destructuring to get the user now if the roles that we've defined here match the role that you get from postman based on the login credentials so if that's true you're allowed to make the requests so we'd want to return true in our roles card but if so they only have to have one of these match the uh three roles we have so there's also a user role so if any sum of those if or like javascript is the function we're going to use method we're going to use for some if any of these are in the roles then that's considered they have the permissions to be able to do that so what we can say and if then if they're not obviously we want to be returning false here so for the required roles and i should mention the shape of required roles required roles is basically it's either you know well if it makes it to here it's got it's got something in it so it might have admin in it or it might have user in it or it might have premium in it and it could also have any combination or multiple of that so for example could have in our case admin and premium so since we have this sort of data structure here we can use a higher order function an array method so we can have sum and what sum does is what we want to do is we want to check that if any of these so admin or premium matches this role here in admin then we want to turn true so for any one of these roles if we have the case so this is just going to return something uh based on if it's true or false so we got the context of our user here which more or less relates to this user with a role so if the user if the role and we tackle this elvis operator because it might not be defined for whatever reason just as an extra safety although it should be defined by this stage [Music] if that includes something from here then it will return true essentially but if it doesn't it will return false so i can go ahead and delete this pseudo code as an using as an example and we can go ahead and we can run our server in development mode by an npm start our npm run start colon dev let's run it and it's just mapping the routes so the application has successfully started so let's look at the role so we've said admin and premium will work so let's let's see in this case where it doesn't work first so i've got this um john user so i can log in as this guy copy the token paste it into the authorization header and if i make the request we get forbidden resource now if i do the same thing but with the admin user we make the request we get the token we copy it in we paste it there and let's just go ahead and change the body to 67 678 we make that and then we see that we've made the actual request so and get the roll back get this nested information of the author the body when it was created the id that it relates to in the table and just to see everything's working if we go to our feed post and we go ahead and look at all the rows you scroll down to the bottom here we see we get the 678 so we've successfully implemented authorization role based authorization so the next steps from here will be to [Music] basically use this in other sections of our application in our api so we're building a linkedin clone so we're going to want to allow users to delete and edit their post um but what happens if you're a user and now we've implemented role-based uh authorization um if you're a user you still more or less have access to be able to change other users data basically so what would want to implement next on the back end side of things is the ability to it's essentially just another guard and it's just to make sure that the users are logged in as the particular user that they are and also if the admin or something like that they can make the request and override that but where i want to continue off in the next videos i want to implement this role-based authorization and authentication on the front-end side of things so we've built out the ui and i want to intercept the requests that we're making from the front-end and attach the token and allow for different things to happen depending on the role type so if you've liked this video please subscribe to my youtube channel i'm nearly at a thousand i'm looking forward to hitting the 1k milestone mark and there's going to be plenty more high quality content coming up just like this so thanks so much for watching and i'll see you in the next one cheers
Info
Channel: Jon Peppinck
Views: 21,071
Rating: undefined out of 5
Keywords: role based access control, role based authorisation in asp.net core, role based authentication passport, role based authentication in node js, rbac, role based authentication in mvc, role based access control node js, role based access control database design, role based access control example, nestjs, role based authentication, role based auth, role based authoriation, role based authorization, role based access controls, authorization, rbac database design
Id: yZWcd77l9jk
Channel Id: undefined
Length: 28min 14sec (1694 seconds)
Published: Thu May 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.