我有点咸菜。我正在使用路由保护(实现CanActivate
接口)来检查用户是否被授予访问特定路由的权限:
const routes: Routes = [
{
path: '',
component: DashboardViewComponent
},
{
path: 'login',
component: LoginViewComponent
},
{
path: 'protected/foo',
component: FooViewComponent,
data: {allowAccessTo: ['Administrator']},
canActivate: [RouteGuard]
},
{
path: '**',
component: ErrorNotFoundViewComponent
}
];
现在它可以很好地保护“/protected/foo”路由不被激活,但我想告诉用户他试图访问的路由是被禁止的(类似于你可能从服务器获得的 403 Forbidden)。
问题:
如何在不将他重定向到错误路线的情况下向用户显示这个特殊的错误视图,而我发现的这么多来源似乎是首选选项?
以及如何在不实际加载禁止路线的情况下使用我RouteGuard
的路线,因为如果我检查我的内部访问FooViewComponent
并显示不同的视图,它RouteGuard
首先会失败。
理想情况下,我希望我RouteGuard
不仅在canActivate()
方法中返回 false,而且还希望用 say 完全替换组件ErrorForbiddenViewComponent
。但我不知道该怎么做,或者是否有可能。有什么选择吗?
这就是我的路由守卫现在的样子:
import {Injectable} from '@angular/core';
import {Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {AuthService} from '../services/auth.service';
@Injectable()
export class RouteGuard implements CanActivate {
constructor(
private router: Router,
private auth: AuthService
) {}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const { auth, router } = this;
const { allowAccessTo } = next.data;
const identity = auth.getIdentity();
if (
identity &&
allowAccessTo.indexOf(identity.role)
) {
// all good, proceed with activating route
return true;
}
if (identity) {
// TODO show ErrorForbiddenViewComponent instead of redirecting
console.log('403 Forbidden >>', next);
}
else {
// not logged in: redirect to login page with the return url
const [returnUrl, returnQueryParams] = state.url.split('?');
console.log('401 Unauthorised >>', returnUrl, returnQueryParams, next);
router.navigate(['/login'], {queryParams: {returnUrl, returnQueryParams}});
}
return false;
}
}
所以我只是阻止路由加载,但我没有重定向。我只将未登录的访问者重定向到登录路线。
推理:
- 路由应该反映应用程序的某些状态 - 访问路由 url 应该重新创建该状态
- 拥有错误路由(404 Not Found 除外)意味着您的应用程序实际上可以重新创建错误状态。这没有任何意义,因为您为什么要将错误状态保留为应用程序的状态?出于调试目的,应该使用日志(控制台或服务器),重新访问错误页面(即页面刷新)可能会干扰这一点。
- 此外,通过重定向到错误路由应用程序应该为用户提供一些错误见解。就此而言,要么需要通过 url 传递某些参数,要么(更糟糕的是)在某些错误服务中保持错误状态并在访问错误路由时检索它。
- 此外,忽略 RouteGuard 并仅加载组件并检查其中的访问权限可能会导致加载一些额外的依赖项,这些依赖项无论如何都不会被使用(因为不允许用户使用),这会使整个延迟加载变得更加困难。
有没有人对此有某种解决方案?我也想知道,在 Angular 2+ 出现这么久之后,为什么以前没有人遇到过这种情况?每个人都可以重定向吗?
还要记住,虽然我目前正在使用FooViewComponent
同步,但将来可能会改变!