我有一个现有的Angular2应用程序,其中通过创建扩展RouterOutlet的AuthRouterOutletDirective来处理登录/身份验证.这使得在activate函数中使用componentInstruction可以很容易地检查用户是否已登录,如果没有将它们重定向到我们的登录门户(由于各种原因我无法控制它是通过一个单独的应用程序,它有自己的登录屏幕然后在导航到下一个组件之前发回一个我们将保存在Angular2应用程序中的令牌.
我刚刚升级到路由器3.0.0-alpha.8,我发现这不再是一个选项,它已被替换为创建一个authGuard并使用canActivate方法来处理身份验证(我指的是这部分documentation).我正在努力解决的问题是,它似乎是专为只保护少量路由的应用而设计的,您只需将canActivate:[AuthGuard]添加到需要在RouterConfig中进行身份验证的每条路由.
我遇到的问题是每条路由都需要通过身份验证来保护.还需要进行连续检查(除非有更好的修复),因为我们(同样部分由于我们必须使用的外部登录服务)将注销用户并清除他们的令牌,并在下次导航到新路线(无论路线是什么)它应该重定向您再次登录.我知道我可以添加canActivate:[AuthGuard]到每一条路线,但这似乎是一个疯狂而乏味的修复,特别是对于拥有大量路由的应用程序,所有这些都需要用户进行身份验证才能查看.
我一直在寻找修复,但似乎也许是因为升级是相当新的,所有资源都是如何在一两条路线上实现这些AuthGuards.我一直在挖掘源代码(特别是here),看看是否有另一种方法可以扩展,比canActivate更全面,或者更通用的方法让每条路线都包含一个特定的守卫,但我似乎无法找到任何东西.任何关于如何最好地实现这一点的建议将非常感谢!谢谢.
最佳答案 参考我的评论,你可以添加额外的警惕:
import {provideRouter, RouterConfig, Route, CanActivate, ActivatedRouteSnapshot} from '@angular/router';
import {Injectable} from "@angular/core";
@Injectable()
class UniversalGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot) {
console.log('applying can activate');
return true;
}
}
let routes: RouterConfig = [
{path: 'path1', component: Component1} as Route,
{path: 'path2', component: Component2} as Route,
{path: 'path3', component: Component3} as Route
];
const routeAugumenter = route => {
let guards = route.canActivate || [];
guards.push(UniversalGuard);
route.canActivate = guards;
if (route.children) {
route.children = route.children.map(routeAugumenter);
}
return route;
};
let augumentedRoutes = routes.map(routeAugumenter);
console.log(augumentedRoutes);
export const APP_ROUTER_PROVIDERS = [
provideRouter(augumentedRoutes), UniversalGuard
];
我没有用子路线测试它,但也应该工作.
编辑:更新信息如何将服务注入到UniversalGuard中.
如果你的守卫需要注入一些服务,你通常会在构造函数中注入它们.您必须在Angular bootstrap调用中而不是在组件中提供这些服务(以及它们所依赖的服务等).