See official Angular docs about routing: https://angular.io/guide/router
And its demo: https://stackblitz.com/angular/pbqlrdpbpvx
The demo demonstrates an admin section which may only be accessed if the auth service state isloggedIn returns true. The section is protected with an canActivate auth-guard.
By nature, the canActivate guard will only fire one time when you try to access the page. And correctly routes you to the login process if your auth service state ìsloggedIn returns false.
However, I need my canActivate guard to fire every time if there is a value change of my auth service state ìsloggedIn, to ensure that if the auth status turns false by itself (i.e. if I use expiry date or something at a later point), to have the user automatically routed off the protected section. He shall not remain on the protected area page if out of all sudden the value changes to false.
Steps to reproduce by adding a simple logout button on the top nav:
- Extend demo (https://stackblitz.com/angular/pbqlrdpbpvx) with logout button on top:
app.component.ts:
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { slideInAnimation } from './animations';
import { AuthService } from './auth/auth.service';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css'],
animations: [ slideInAnimation ]
})
export class AppComponent {
constructor(public authService: AuthService) {}
getAnimationData(outlet: RouterOutlet) {
return outlet && outlet.activatedRouteData && outlet.activatedRouteData['animation'];
}
logout() {
this.authService.logout();
}
}
app.component.html:
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/superheroes" routerLinkActive="active">Heroes</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a routerLink="/login" routerLinkActive="active">Login</a>
<a (click)="logout()" *ngIf="authService.isLoggedIn">Click To Logout</a>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
</nav>
<div [@routeAnimation]="getAnimationData(routerOutlet)">
<router-outlet #routerOutlet="outlet"></router-outlet>
</div>
<router-outlet name="popup"></router-outlet>
Click on the login button and login - you will be routed to the admin section and the logout button on the top nav will show.
Click on the Logout button and see that the view remains unchanged. You are still on the admin section.
Intended behaviour:
If the auth service's isLoggedIn state turns false, the user shall automatically be redirected to the login page. As such, the anActivate guard should fire automatically on value change.
Reason for current behaviour:
The auth guard's canActivate which determines if you can access the page or not only is checked against only once in the beginning when you enter the page.
Current solution:
Extending the click functionality of the logout-button with a route-call to the login section. This however does not cover all the use cases.
Thanks in advance.