I am currently working on implementing a guard to prevent users from navigating to the login page once they have authenticated themselves. This guard should apply to all page components in my app except for the login page.
Below is the code snippet I am using:
import { Injectable } from '@angular/core';
import { Router, ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree, CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthenticationService } from '../services/authentication.service';
@Injectable({ providedIn: 'root' })
export class AuthGuard<T> implements CanActivate, CanDeactivate<T> {
constructor(private router: Router, private auth: AuthenticationService) {
}
canActivate(
_route: ActivatedRouteSnapshot,
_state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.auth.isAuthenticated() || this.router.navigate(['/login']);
}
canDeactivate(
_component: T,
_currentRoute: ActivatedRouteSnapshot,
_currentState: RouterStateSnapshot,
nextState: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if (nextState && nextState.url.includes('/login')) {
return !this.auth.isAuthenticated();
}
return true;
}
}
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from './guards/auth.guard';
import { HomeComponent } from './pages/home/home.component';
import { LoginComponent } from './pages/login/login.component';
const routes: Routes = [
{
path: 'login',
component: LoginComponent
},
{
path: 'home',
component: HomeComponent,
canActivate: [AuthGuard],
canDeactivate: [AuthGuard]
},
{
path: '**',
redirectTo: 'home',
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: [AuthGuard]
})
export class AppRoutingModule { }
I have also experimented with implementing a new canActivate guard specifically for the login component, which works but I am not fully satisfied with this approach.
I have come across examples like the one at . It seems using an interface in this context may not be the best practice as TypeScript does not support default method implementation. I seek a solution where I do not have to repeat the validation on every component.
Why is my current implementation not being called? How can I better approach this?
Any suggestions or guidance on this matter would be highly appreciated.
Additional information: Angular v14.1.3