Public routes
Routes that don't require authentication.
What we'll do now is to apply the JwtAuthGuard
globally, and on the routes that should be public, we'll add the @Public()
decorator, yet to be created.
So, after removing the guard from the getProfile()
route, let's go to the AuthModule
and add it in its providers
globally.
Now the getProfile()
route is still protected, but the login()
route, which obviously should be public, became inaccessible. Let's then create the file auth -> decorators -> public.decorator.
If we place this decorator over a route, what will happen is that it will have the metadata isPublic
set to true. We also use the IS_PUBLIC_KEY
constant to be able to access this metadata in a type-safe manner. But how do we actually implement this public behavior?
This will be done inside the JwtAuthGuard
. Currently, it just checks if the token is valid. We'll just make it also check first if the isPublic
metadata is present in the route. In a positive case, it will instantly allow access. Otherwise, it will continue with its normal flow. Let's then begin.
The first step is to add a constructor
that calls super()
, so that the guard is initialized normally. But now also adding a Reflector
, which allows to access the route's metadata.
And now we'll override the canActivate()
method, which is a guard's method for deciding whether access should be granted or denied.
The way to obtain the metadata may seem a bit confusing, but what's happening here is nothing too complicated. If desired, we can use the @Public()
decorator over an entire controller, in order to make all its routes public at once. So the guard checks both the controller and the individual routes to collect the metadata.
Here, getHandler()
refers to the route and getClass()
refers to the controller.
If there was metadata in both the controller and one of its routes, then the one in the route would take precedence, hence the getAllAndOverride()
method.
The remainder has already been explained: if isPublic
is present, allow access; if not, continue with the normal behavior.
We can now return to the AuthController
and add @Public()
over the login()
route. Now, all the routes of our system require a valid JWT to be accessed, except if declared as public.
Commit - Global JWT guard and decorator for public routes
We can now use the @Public()
decorator over some routes where it may make sense, like:
find()
routes in theProductsController
CategoriesController
create()
route in theUsersController
Commit - Marking public routes
Last updated