Reputation: 1271
I'm trying to put access checks for routes and display access denied page instead of actual page. From the example below we can alert access denied on route click . I would prefer to navigate to the actual page and then show Access denied.
http://plnkr.co/edit/w1NCkGs0Tv5TjivYMdvt?p=preview
lets say url with access check is /admin/manageusers
and component name is ManageUserComponent
and if a user don't have access and tries the url, it should navigate to the route /admin/manageusers
but should be showing Access Denied in the page
.
1.One thing i can do is to use route resolve
feature and get the value related to users access and in ManageUserComponent
and switch the template. This approach will endup having similar code in multiple components associated with routes where i want to implement access logic.
component
where access check needed extends another base class
and validate above logic , if success then allow child component to proceed. Yet to figure out how to extend another class properlyMain goal is to preserve the accessed url with error message in the page. And the component functions should not execute.
If you can think of approaches and options to implement, please share.
If the description is not clear please let me know, i will try to make it better.
Upvotes: 4
Views: 4589
Reputation: 162
You can do something like this on the app-routing.module.ts
// PRIVATE ROUTES
{
path: 'dashboard',
component: DashboardComponent,
canActivate: [LoggedInGuard]
},
then define this LoggedInGuard service
// logged-in.guard.ts
import { Injectable } from '@angular/core';
import { Router, CanActivate } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class LoggedInGuard implements CanActivate {
constructor(
private _router: Router,
private _authService: AuthService) { }
canActivate() {
// return true
if (this._authService.isLogged()) {
// all ok, proceed navigation to routed component
return true;
}
else {
// redirect to the homepage
this._router.navigate(['/'], { skipLocationChange: true });
// abort current navigation
return false;
}
}
}
Hope this may help you out.
Upvotes: 5
Reputation: 697
Implement CanActivate
logic
Implement guarded component and add route to it (for instance: 'denied').
Use skipLocationChange
option to navigate in router
@Injectable()
export class CanActivateRequestForm implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<boolean>|Promise<boolean>|boolean {
let obs = this.authService.userChange.asObservable().map(({role}) => role === Role.Admin);
obs.subscribe(v => {
if (!v)
this.router.navigate(['denied'], {
skipLocationChange: true
});
});
return obs;
}
}
Upvotes: 1