Angular AuthGuard Not Blocking Access When Directly Navigating to blocked Routes

Discussão em 'Angular' iniciado por Anas B, Março 3, 2025.

  1. Anas B

    Anas B Guest

    I'm working on an Angular application where I want to prevent authenticated users from accessing the login and signup pages. I have implemented an AuthGuard to handle this. The guard works as expected when navigating within the application using Angular's router, but it fails to block access when the user directly enters the login or signup URL in the browser's address bar.

    when the application starts it attempts to get current user

    app.component.ts - - >

    @Component({
    selector: 'app-root',
    standalone: true,
    imports: [
    RouterOutlet,
    RouterModule,
    LoaderComponent,
    NotFoundComponent,
    NavigationComponent,
    NotificationComponent,
    ],
    templateUrl: './app.component.html',
    styleUrl: './app.component.scss',
    })
    export class AppComponent implements OnInit {
    authService = inject(AuthService);
    destroy = inject(DestroyRef);
    title = 'book store';
    router = inject(Router);
    ngOnInit(): void {
    if (localStorage.getItem('accessToken')) {
    this.authService
    .getCurrentUser()
    .pipe(takeUntilDestroyed(this.destroy))
    .subscribe();
    }
    }
    }



    auth.service.ts relevant part - - >


    currentUser: WritableSignal<CurrentUser | null | undefined> = signal(undefined);

    getCurrentUser(): Observable<CurrentUser> {
    return this.http.get<CurrentUser>(`${environment.API_URL}/auth/user`).pipe(
    tap((response) => {
    this.currentUser.set(response);

    })
    );
    }


    app.routes.ts relevant part - - >

    {
    path: 'login',
    loadComponent: () =>
    import('./components/auth/login/login.component').then(
    (m) => m.LoginComponent
    ),
    data: { title: 'login' },
    canActivate: [authGuard],
    },
    {
    path: 'signup',
    loadComponent: () =>
    import('./components/auth/signup/signup.component').then(
    (m) => m.SignupComponent
    ),
    data: { title: 'signup' },
    canActivate: [authGuard],
    },


    my problem is that the my guard uses currentUser signal from AuthService and the value emitted by the signal is undefined when the guard is executed witch allows the user to access the blocked page.

    auth.guard.ts - - >

    import { inject } from '@angular/core';
    import { Router, type CanActivateFn } from '@angular/router';
    import { AuthService } from '../services/auth.service';

    export const authGuard: CanActivateFn = (_route, _state) => {
    const authService = inject(AuthService);
    const router = inject(Router);

    const user = authService.currentUser();
    // when I directly enter the login or signup URL I see AuthGuard: currentUser: undefined
    console.log('AuthGuard: currentUser:', user);

    if (user === null || user === undefined) {

    // I see this log when I directly enter the login or signup URL in the browser's address bar

    console.log('AuthGuard: No user found, allowing access.');
    return true;
    } else {

    // the guard works correctly when I navigate to /login or /signup from a router link or by going back

    console.log('AuthGuard: User found, redirecting to home.');
    router.navigateByUrl('/');
    return false;
    }
    };



    Any insights or suggestions to ensure the guard works correctly regardless of how the route is accessed would be greatly appreciated!

    Continue reading...

Compartilhe esta Página