0

I am trying to implement guards in my Angular application. So far I have 3 guards setup, but I would like to have them setup in an OR or ANY mode, where if any of the guards allow the request the route can be activated.

Does someone have a way of doing this?

My guards are quite simple with all three looking the same as follows:

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
import { AppSettings } from './AppSettings';

@Injectable({ providedIn: 'root' })
export class GuardianGuard implements CanActivate {
    constructor(
        private router: Router,
        private http: HttpClient
    ) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
        //Get the users role from the API based on the JWT they were authenticated with
        return this.http.get(`${AppSettings.API_ENDPOINT}/Role`).pipe(map(data => {
            //Check if the returned server role is that of the guardian
            if (data === "3") {
                //Allow the action if it is
                return true;
            } else {
                //Return to login and deny action if it is not
                this.router.navigate(['/login']);
                return false;
            }
        }));
    }
}
Tachyon
  • 2,171
  • 3
  • 22
  • 46
  • why don't you move the logic inside guards in a service with 3 methods and then in same gaurd put or condition with these 3 methods – jitender Aug 07 '19 at 12:21
  • You could also have each guard add a data object to the navigation if it is successfully authenticated. Each guard would then check for that data object, and automatically authenticate any previously authenticated request. – Will Alexander Aug 07 '19 at 12:24

1 Answers1

1

You can have a common having 3 methods with activation logic of each gaurd something like

export class YourService(){

firstCondition(){
//return boolean
}

secondCondition(){
//return boolean
}

thirdCondtion(){
//return boolean
}

}

then create another gaurd that will have logic something like

 canActivate(){
  return yourServiceRef.FirstCondition() || yourServiceRef.SecondCondition()....
 } 

Also, you can use same service with your old guards calling respective method;

jitender
  • 10,238
  • 1
  • 18
  • 44
  • This would mean I would need to create a auth guard for each combination of my auth roles. Isn't there a way to create a class that can take my auth guards as constructor parameters and then activate the correct guards based on that? – Tachyon Aug 07 '19 at 12:47
  • @Tachyon in that case you can pass gaurdtype in data param of router and can have logical implementation in your gaurd https://stackoverflow.com/a/42721468/5621827 – jitender Aug 08 '19 at 03:50