> For the complete documentation index, see [llms.txt](https://kinesis-school-of-programming.gitbook.io/nestjs-unleashed/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kinesis-school-of-programming.gitbook.io/nestjs-unleashed/extra-module-1-authentication-authorization/authentication/public-routes.md).

# Public routes

Routes that don't require authentication.

What we'll do now is to apply the <mark style="color:blue;">`JwtAuthGuard`</mark> globally, and on the routes that should be public, we'll add the <mark style="color:blue;">`@Public()`</mark> decorator, yet to be created.

So, after removing the guard from the <mark style="color:blue;">`getProfile()`</mark> route, let's go to the <mark style="color:blue;">`AuthModule`</mark> and add it in its <mark style="color:blue;">`providers`</mark> globally.

```typescript
{
  provide: APP_GUARD,
  useClass: JwtAuthGuard,
},
```

Now, the <mark style="color:blue;">`getProfile()`</mark> route is still protected, but the <mark style="color:blue;">`login()`</mark> route, which obviously should be public, became inaccessible. Let's then create the file <mark style="color:purple;">auth</mark>/<mark style="color:purple;">decorators</mark>/<mark style="color:purple;">public.decorator</mark>.

```typescript
export const IS_PUBLIC_KEY = 'isPublic';

export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
```

If we place this decorator over a route, what will happen is that it will have the metadata <mark style="color:blue;">`isPublic`</mark> set to true. We also use the <mark style="color:blue;">`IS_PUBLIC_KEY`</mark> 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 <mark style="color:blue;">`JwtAuthGuard`</mark>. Currently, it just checks if the token is valid. We'll just make it also check first if the <mark style="color:blue;">`isPublic`</mark> 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 <mark style="color:blue;">`constructor`</mark> that calls <mark style="color:blue;">`super()`</mark>, so that the guard is initialized normally. But now, while also adding a <mark style="color:blue;">`Reflector`</mark>, which allows to access the route's metadata.

```typescript
constructor(private readonly reflector: Reflector) {
  super();
}
```

And now, we'll override the <mark style="color:blue;">`canActivate()`</mark> method, which is a guard's method for deciding whether access should be granted or denied.

```typescript
canActivate(context: ExecutionContext) {
  const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
    context.getHandler(),
    context.getClass(),
  ]);

  if (isPublic) return true;

  return super.canActivate(context);
}
```

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 <mark style="color:blue;">`@Public()`</mark> decorator over an entire controller, in order to make all of its routes public at once. So, the guard checks both the controller and the individual routes to collect the metadata.

{% hint style="info" %}
Some notes:

* Here, <mark style="color:blue;">`getHandler()`</mark> refers to the route and <mark style="color:blue;">`getClass()`</mark> 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 <mark style="color:blue;">`getAllAndOverride()`</mark> method
  {% endhint %}

The remainder has already been explained: if <mark style="color:blue;">`isPublic`</mark> is present, allow access; if not, continue with the normal behavior.

We can now return to the <mark style="color:blue;">`AuthController`</mark> and add <mark style="color:blue;">`@Public()`</mark> over the <mark style="color:blue;">`login()`</mark> route. Now, all the routes of our system require a valid JWT to be accessed, except if declared as **public**.

<mark style="color:green;">**Commit**</mark> - Global JWT guard and decorator for public routes

We can now use the <mark style="color:blue;">`@Public()`</mark> decorator over some routes where it may make sense, like:

* <mark style="color:blue;">`find()`</mark> routes in the
  * <mark style="color:blue;">`ProductsController`</mark>
  * <mark style="color:blue;">`CategoriesController`</mark>
* <mark style="color:blue;">`create()`</mark> route in the <mark style="color:blue;">`UsersController`</mark>

<mark style="color:green;">**Commit**</mark> - Marking public routes
