Angular Role Based Protection from Client Side Question

322 views Asked by At

I am new to angular and have been googling about this but haven't really found anything helpful (probably my google terms I'm using).

In a traditional server side application, you can generate a page which has different controls/functions/layout/etc based on the authenticated user. Because this is all done on the server side, two different users (who see two different things) have no idea what the other user might see. Since it is all server side, no way to run fiddler or some other tool to extract all the typescript/javascript/html/etc.

In angular, lets say you have routes for roles ClientRole => /pages/1, /pages/2 AdminRole => /pages/1, /pages/2, /pages/admin/1, /pages/admin/2

For the routes, I am guessing you would just send a new route list through an observable/ngrx store anytime the user auth changed to update the list of routes (thus preventing someone from going through the "routes file" to see there is a "/page/admin" route defined if they aren't in a role that has that route)?

How could this work with components? So that if someone were to try to reverse engineer the client side components, they wouldn't even have the "admin components" on the client side unless they were logged in and in the admin role?

1

There are 1 answers

2
Peter Kim On

Let your jwt token contain something like level that can be either "user" or "admin". Once they're logged in, you can call isLoggedIn() in your guard service.

So in your auth.service.ts:

private isLoggedInAs = new BehaviorSubject<any>('');
isLoggedIn = this.isLoggedInAs.asObservable();

// check if user is logged in, and if so with what level
public isLoggedIn() {
    // insert relevant filters that will return false
    const jwtpayload = jwt.decode(this.getToken());
    this.updateLoggedIn(jwtpayload.level);
    return true;
}

updateLoggedIn(level: string) {
  this.isLoggedInSource.next(level);
}

And in your guard.service.ts:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    if (this.authService.isLoggedIn()) {
        this.router.navigate(['/pages']);
        return false;
    } else {
        return true;
    }
}

And wherever you need to know their level, you can do something like this:

ngOnInit() {
    this.authService.isLoggedIn.subscribe(isLoggedIn => {
        if (isLoggedIn) {
            this.isLoggedIn = isLoggedIn;
        } else {
            this.isLoggedIn = 'anonymous';
        }
    });
}