AccessRole Guard for Angular apps - https://salvagni.dev/2019/09/accessrole-guard-for-angular-apps/
import { Injectable } from '@angular/core'; | |
import { | |
ActivatedRouteSnapshot, | |
CanActivate, | |
Router, | |
RouterStateSnapshot, | |
} from '@angular/router'; | |
import { Observable } from 'rxjs'; | |
import { map } from 'rxjs/operators'; | |
import { AuthService } from '../services/auth.service'; | |
/** | |
* Implements a Route Guard that will confirm that an authenticated user | |
* has the roles informed on route data object. | |
*/ | |
@Injectable({ | |
providedIn: 'root' | |
}) | |
export class AccessRoleGuard implements CanActivate { | |
constructor( | |
private router: Router, | |
private authService: AuthService | |
) { } | |
canActivate( | |
next: ActivatedRouteSnapshot, | |
state: RouterStateSnapshot): Observable<boolean> { | |
const roles = next.data && next.data.roles || []; | |
return this.authService | |
.hasSomeOfTheseRoles(roles) | |
.pipe( | |
map((response: boolean): boolean => { | |
if (response) return true; | |
this.router.navigate(['/not-authorized']); | |
return false; | |
}) | |
); | |
} | |
} |
import { Injectable } from '@angular/core'; | |
import { Observable, of } from 'rxjs'; | |
import { map } from 'rxjs/operators'; | |
/** Describe the available user roles */ | |
export enum AccessRole { | |
Admin = 'Admin', | |
Author = 'Author', | |
Member = 'Member' | |
} | |
/** | |
* Authentication service | |
* It should validate if the logged user has a given set of roles. | |
*/ | |
@Injectable({ | |
providedIn: 'root' | |
}) | |
export class AuthService { | |
/** | |
* Retrieve all the available roles from the logged user. | |
*/ | |
getUserRoles(): Observable<AccessRole[]> { | |
// Return the users roles | |
// Hard-coded here for example purposes | |
return of([AccessRole.Author, AccessRole.Member]); | |
} | |
/** | |
* Verify if the user has at least one role of those passed in the argument. | |
* This is useful for Guards that accept one or more Access Role. | |
*/ | |
hasSomeOfTheseRoles(roles: AccessRole[]): Observable<boolean> { | |
return this.getUserRoles() | |
.pipe( | |
map((userRoles: AccessRole[]) => userRoles.some(role => roles.includes(role))) | |
); | |
} | |
} |
import { NgModule } from '@angular/core'; | |
import { RouterModule, Routes } from '@angular/router'; | |
import { AccessRole } from './services/auth.service'; | |
import { AccessRoleGuard } from './guards/access-role.guard'; | |
import { MemberComponent } from './member.component'; | |
/** | |
* Define in the route which user access role is allowed to access this route. | |
*/ | |
const routes: Routes = [{ | |
path: '/member', | |
component: MemberComponent, | |
canActivate: [AccessRoleGuard], | |
data: { | |
roles: [AccessRole.Member, AccessRole.Author] | |
} | |
}]; | |
@NgModule({ | |
imports: [RouterModule.forChild(routes)], | |
exports: [RouterModule] | |
}) | |
export class MemberModule { } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment