angularauthenticationangular-routinguser-rolesangular-guards

Angular router: navigating to different routes according to the user's role


I'm writing a mock e-commerce app which has the following structure:

The basic workflow is supposed to be as follows:

  1. The user navigates to the root path /.
  2. The application detects that they are not logged in, so it redirects them to /signin.
  3. They enter their credentials and press Sign In.
  4. If the authentication is successful,
    1. If the user is an admin, they get redirected to /admin.
      1. admin-router.module.ts redirects them to some sub-path of /admin.
    2. If the user is a customer, they get redirected to /customer.
      1. customer-router.module.ts redirects them to /customer/catalog/<default category ID>.
      2. They put some products in the shopping cart and proceed to /customer/checkout.
      3. They place the order and get redirected to /customer/thankyou.

What I'm not sure about is how to accomplish the redirection following a successful log-in. Obviously it has to be done in two stages: first to some common path such as / and then either to /customer or to /admin depending on the user's role. The second stage probably needs to be handled by app-routing.module.ts, perhaps using a guard, but I'm not sure exactly how to do it.

EDIT (2021-04-20)

The problem can be summarized as follows:

What I need is a way (preferably declarative) to redirect the application from / to one of the following paths depending on its state:

State Path
Logged out /auth
Logged in as a customer /customer
Logged in as an admin /admin

Solution

  • What I ended up doing is this:

    // app-routing.module.ts
    
    const routes: Routes = [
      {
        path: '',
        canActivate: [AuthorizationGuard],
        children: [],
      },
      { path: '**', component: NotFoundPage },
    ];
    
    // authorization.guard.ts
    
    @Injectable({
      providedIn: 'root',
    })
    export class AuthorizationGuard implements CanActivate {
    
      constructor(private router: Router, private authService: AuthService) {}
    
      canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
      ): UrlTree {
        const user = this.authService.getLoggedInUser();
        return (
          (user?.role === 'admin' && this.router.parseUrl('/admin')) ||
          (user?.role === 'customer' && this.router.parseUrl('/customer')) ||
          this.router.parseUrl('/auth')
        );
      }
    
    }