Skip to content
View lessons Login
3d cartoon hands holding a phone

Unlock full course by purchasing a membership

Protecting Routes with Guards in Angular

Protecting Routes with Guards in Angular

The last feature we are going to add is to prevent unauthenticated users from getting to the home page, and to auto redirect logged in users to the home page. Firebase will remember users automatically, so if we are already logged in we should go directly to the home page.

Redirecting the User

Before we create our guard which will help keep our user where they are supposed to be, we are going to implement some redirects that react to the user’s auth state changing.

The problem in our application right now is that when we try to log in or create an account… nothing happens.

These operations are actually happening successfully, it’s just that our application doesn’t care. What we need to do is have our components react to the authState from Firebase changing by triggering a navigation. We already have a convenient way to do this. Whenever our authState observable emits we set our user state in our AuthService. This results in the following possibilities:

  • If we do not yet know if the user is authenticated, the user() signal will be undefined
  • If the user is unauthenticated the user() signal will be null
  • If the user is authenticated the user() signal will be the User from Firebase

This user() signal updates automatically whenever we change the user’s authState in any way — whether that happens because of a login, logout, create account, or anything else.

We also have a convenient way to trigger running some code, like a navigation, by using the effect Signal API. That means we can just add some effects to each of our components to handle the navigation:

  • The LoginComponent should react by navigating to the home route when the user() signal becomes truthy (i.e. not null or undefined)
  • The RegisterComponent should do the same
  • The HomeComponent should react by navigating to the auth/login route when the user() signal becomes null

See if you can implement this before continuing.

private router = inject(Router);
constructor() {
effect(() => {
if (this.authService.user()) {
this.router.navigate(['home']);
}
});
}
private router = inject(Router);
constructor() {
effect(() => {
if (this.authService.user()) {
this.router.navigate(['home']);
}
});
}
private router = inject(Router);
constructor() {
effect(() => {
if (!this.authService.user()) {
this.router.navigate(['auth', 'login']);
}
});
}

Now if you try to use the application it should actually appear to work correctly (although it will still look ugly). However, if you happen to have logged in before you will automatically be taken to the home route. This is good, but we don’t actually have a way to trigger a log out, so you will be stuck there.

<div class="container">
<mat-toolbar color="primary">
<span class="spacer"></span>
<button mat-icon-button (click)="authService.logout()">
<mat-icon>logout</mat-icon>
</button>
</mat-toolbar>
<app-message-list [messages]="messageService.messages()" />
<app-message-input (send)="messageService.add$.next($event)" />
</div>
imports: [
MessageListComponent,
MessageInputComponent,
MatIconModule,
MatButtonModule,
MatToolbarModule,
],
EXTENDED EXTENDED

Thanks for checking out the preview of this lesson!

You do not have the appropriate membership to view the full lesson. If you would like full access to this module you can view membership options (or log in if you are already have an appropriate membership).