Requiring permissions
Routes may now require one of a set of roles to be accessed.
A decorator will be used to define the necessary roles
for a route. Let's then create it in auth -> decorators -> roles.decorator. Notice that it accepts an array of roles
.
Another approach would be to define the decorator like this. It may be interesting in simple cases where the passed metadata should simply be appended to the route. You can read more about it here.
Afterwards, we'll create our first guard from scratch, the RolesGuard
. As can be guessed, it will protect the routes according to the necessary roles
.
Underneath we can see a basic skeleton, with a reflector
and the canActivate()
signature.
Inside the canActivate()
method, the first step is to collect the roles
metadata from the route (or controller). Remember that, if there is metadata for both the controller and a route, then the one from the route will be used. If there is no metadata, this guard will be out of the way.
We could also use getAllAndMerge()
for merging the metadata of controller and route together, if this behavior was desired.
Then, the user
is extracted from the request
. The Request
type is from express
, which has a user
interface in it. As we are sure that the user
in the request
will always have the fields in the RequestUser
interface, we can make the type assertion to it without weighing our conscience. Lastly, check if the user
is an ADMIN
, immediately giving access in positive case.
And finally, check if the user
has one of the required roles.
Now, the RolesGuard
can be activated globally, after the JwtAuthGuard
.
It's important to follow this order! Otherwise, the guards' behavior will be compromised.
We can then state that a route requires one or more roles like the following:
Commit - Global roles guard and decorator for required roles in routes
With this, we can start to protect some routes. For example, we can require the MANAGER
role
for the following routes:
create()
,update()
andremove()
routes in theProductsController
CategoriesController
find()
routes in theUsersController
And require the ADMIN
role
for the assignRole()
route.
Commit - Requiring roles in some routes
Last updated