我有一点咸菜。
我正在使用路由保护(实现 CanActivate
接口(interface))来检查用户是否被授予访问特定路由的权限:
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)。
问题:
如何向用户显示这个特殊的错误 View ,而不将他重定向到错误路线,这似乎是我发现的许多来源的首选选项?
我如何仍然使用我的 RouteGuard
而无需实际加载禁止的路线,因为如果我检查 FooViewComponent
内部的访问并显示不同的 View 击败了首先拥有 RouteGuard
的点。
理想情况下,我希望我的 RouteGuard
不仅在 canActivate()
方法中返回 false,而且还用 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;
}
}
所以我只是阻止路由加载,但我没有重定向。我仅将未登录的访问者重定向到登录路线。
推理:
- 路线应反射(reflect)特定的应用状态 - 访问路线 url 应重新创建该状态
- 拥有错误路由(404 Not Found 除外)意味着您的应用程序实际上可以重新创建错误状态。这没有意义 为什么您要将错误状态保留为应用程序的状态?为了 调试目的应该使用日志(控制台或服务器),重新访问 错误页面(即页面刷新)可能会干扰这一点。
- 此外,通过重定向到错误路线,应用程序应该向用户提供一些错误见解。就此而言,某些参数需要 通过 url 传递或(更糟糕)将错误状态保留在某些错误中 服务并在访问错误路由时检索它。
- 此外,忽略 RouteGuard 并仅加载组件并检查其内部的访问可能会导致一些额外的依赖项 无论如何都不会使用的已加载(因为不允许用户),使得 整个延迟加载更加困难。
有人对此有某种解决方案吗?我还想知道,为什么 Angular 2+ 出现这么久之后,以前没有人遇到过这种情况?大家都同意重定向吗?
另请记住,虽然我当前正在同步使用 FooViewComponent
,但将来可能会发生变化!
最佳答案
我曾经解决过类似的问题。
分享我的stackblitz poc我创建的地方 -
- 经过身份验证的组件(带防护)
- 登录组件
- 权限守卫
- 路由(
/auth
路由由PermissionGuardService
防护提供)
guard 正在评估用户类型并相应地处理重定向/错误。
用例是 -
- 用户未登录(
显示带有登录消息的 Toast
) - 用户不是管理员(
显示带有未经授权的消息的 Toast
) - 用户是管理员(
显示成功消息的 toast
)
我已将用户存储在本地存储中。
如果您需要特殊处理,请告诉我,我将更新代码库。
干杯!
关于angular5 - 角度 5/6 : protect route (route guard) without redirecting to error route,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50477745/