avvensis
avvensis

Reputation: 955

How to get current route guard

I'm making an app with some protected pages inside This pages are accessible only for registered users. Some times i should check session for timeout or after change browser tab. If user already exit in other tab or session expired, the app should redirect user to login page.

I'm using guards to protect pages so i think it correct way to check current route by his guard. Page should by redirected if user session expired/closed and current route uses certain guard.

Could anybody help to get guards of the current route?

I checked docs for Router and ActivatedRoute and don't find any information about that.

Upvotes: 7

Views: 5245

Answers (5)

igorsp7
igorsp7

Reputation: 451

Here's what I think is a better an a more general implementation of a hasGuard check. It checks for existance of an arbitrary guard anywhere on the tree of ActivatedRouteSnapshot given by its root node.

function hasGuard(route: ActivatedRouteSnapshot, 
                  selector: (r : Route) => any[] | undefined, 
                  guard: any) : boolean {
  const guards = route.routeConfig ? selector(route.routeConfig) : undefined;
  if (guards)
    for (const g of guards)
      if (g == guard)
        return true;
  for (const child of route.children)
    if (hasGuard(child, selector, guard))
      return true;
  return false;
}

It can be used, for example, like this:

hasGuard(this.router.routerState.snapshot.root, r => r.canActivate, authGuard)

Here authGuard is the actual CanActivateFn set up in the routes array.

Upvotes: 0

mbojko
mbojko

Reputation: 14669

You can put runGuardsAndResolvers: 'always' in the route(s) configurations, and simply try reloading the route (something like this.router.navigate([], {relativeTo: this.route }), where route is the component's instance of ActivatedRoute).

Upvotes: 1

Adrian Gutierrez
Adrian Gutierrez

Reputation: 21

I implemented this solution in the authentication library of my company , you can implement this in a service and consume in any place to check if the current route has implemented your guard


function hasGuard(guardTypeArray: string[], guardName: string) {
  const currentRouteConfig = this.router.config.find(f => f.path === this.router.url.substr(1));
  let hasGuard = false;

  if (currentRouteConfig) {
    for (const guardType of guardTypeArray) {
      if (!hasGuard) {
        if (currentRouteConfig[guardType] ) {
          for (const guard of currentRouteConfig[guardType]) {
            if (guard.name === guardName) {
              hasGuard = true;

              break;
            }
          }
        }
      } else {
        break;
      }
    }
  }
  return hasGuard;
}


// Calling it


const check = hasGuard([
    'canActivate',
    'canActivateChild'
  ], 'AuthGuardService');

Upvotes: 1

ace lafit
ace lafit

Reputation: 259

I was facing this issue also. So I did a little resarch and fiddling and developed this solution:

Assuming the AuthService is implemented like in https://angular.io/guide/router#canactivate-requiring-authentication.

In the AuthService add the following:

Logout() {
// (logout logic here)
  var currentRouteConfig = this.router.config.find(f=>f.path == this.router.url.substr(1));
  if(currentRouteConfig != null && currentRouteConfig.CanActivate != null)  {
    this.redirectUrl = this.router.url;
    this.router.navigate(['/login'])
}

The substr(1) just removes the leading '/' as the path in the router config is without it.

Please keep in mind, that this is a naive implementation assuming that the canActivate is always implementing an authentication guard. Other logic may need deeper checking for authentication guards.

Upvotes: 5

eugene_2005
eugene_2005

Reputation: 116

I face exactly the same issue. Here is a scenario to better understand the need. Imagine you have a website where some pages are protected and some are not. A guard is used to protect appropriate pages. Now imagine user is on protected page (let's say viewing profile) and clicks 'Logout' button. What should happen? User should be redirected to a home page. But if user is on a page that is not protected by guard nothing should really happen. Of course it's possible to check it on every signle page if redirect should happen but it's not the best solution. A better solution would be to handle this situation in AuthService, where logging out is acctually happens but for that someone needs to know if currectly active route is protected by guard or not.

Upvotes: 4

Related Questions