'How to redirect to an Angular custom made Login page if the user is not logged in

In my current case I have an Angular application with Azure AD and MSAL v2 implementation. What I want to achieve is when the user is not logged in redirecting them to the custom made Login page with a simple Login (click)="login()" button. I've followed this project to get where I am now but unfortunately after navigating to ' / ' path of localhost:4200 I am getting redirected straight to the Microsoft login page instead of ' /login '. Am I missing something here? Here is my routing module:

const routes: Routes = [
  {
    path: '',
    component: HomeLayoutComponent,
    canActivate: [MsalGuard],
    children: [
      { path: '', component: WelcomeComponent, pathMatch: 'full'},
      { path: 'map-requests', component: MapRequestsComponent},
      { path: 'map-requests/map-request/details', component: MaprequestDetailComponent }
    ]
  },
  {
    path: '',
    component: LoginLayoutComponent,
    children: [
      {
        path: 'login',
        component: LoginComponent
      }
    ]
  },
  { path: '**', redirectTo: '' }
];

Found similar question on stack: this



Solution 1:[1]

Thanks to this post I found the solution, the solution is to add a second guard which will check if a user is logged in or not, this is how the auth guard looks like.

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import { MsalBroadcastService, MsalService } from '@azure/msal-angular';
import { InteractionStatus } from '@azure/msal-browser';
import { Observable, of } from 'rxjs';
import { filter, switchMap } from 'rxjs/operators';

@Injectable({ providedIn: 'root' })
export class CanActivateGuard implements CanActivate {
    constructor(private msalService: MsalService,
        private router: Router,
        private msalBroadcastService: MsalBroadcastService) { }

    canActivate(route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
        return this.msalBroadcastService.inProgress$
            .pipe(
                filter((status: InteractionStatus) => status === InteractionStatus.None),
                switchMap(() => {
                    if (this.msalService.instance.getAllAccounts().length > 0) {
                        return of(true);
                    }

                    this.router.navigate( ['/auth/login'] );
                    return of(false);
                }),
            );
        }
}

Note: Depending on your rxjs version, you may need to import operators from rxjs library like this

import { Observable, of, filter, switchMap } from 'rxjs';

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Touqeer