在 Angular2 rc3 中是否有比守卫更全面的方法来处理身份验证?
Is there a more comprehensive way to handle authentication in Angular2 rc3 than guards?
我有一个现有的 Angular2 应用程序,其中 login/authentication 是通过创建扩展 RouterOutlet
的 AuthRouterOutletDirective
来处理的。这使得在激活函数中使用 componentInstruction
来检查用户是否已登录变得容易,如果没有将他们重定向到我们的登录门户(出于各种原因,我无法通过单独的应用程序控制它,它具有它是自己的登录屏幕,然后在导航到下一个组件之前发回我们将保存在 Angular2 应用程序中的令牌。
我刚刚升级到路由器 3.0.0-alpha.8,我发现这不再是一个选项,它已被创建 authGuard 并使用 canActivate
方法处理身份验证所取代(我指的是 documentation 的这一部分)。我正在努力解决的问题是,这似乎是为只有少量路由受到保护的应用程序设计的,您只需将 canActivate: [AuthGuard]
添加到 RouterConfig 中需要身份验证的每个路由即可。
我遇到的问题是每条路由都需要通过身份验证来保护。还需要持续检查(除非有更好的解决方案),因为我们也会(部分原因是我们必须使用外部登录服务)注销用户并清除他们的令牌,下次您导航到新路线(无论路线是什么)它应该重定向您再次登录。我知道我可以将 canActivate: [AuthGuard]
添加到每条路线,但这似乎是一个疯狂而乏味的修复,特别是对于具有大量路线的应用程序,所有这些都需要用户经过身份验证才能查看。
我一直在寻找修复程序,但似乎(可能部分是因为升级是相当新的)所有资源都用于如何仅在一两个路由上实施这些 AuthGuard。我一直在挖掘源代码(特别是 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 调用中而不是在组件中提供这些服务(以及它们所依赖的服务等)。
我有一个现有的 Angular2 应用程序,其中 login/authentication 是通过创建扩展 RouterOutlet
的 AuthRouterOutletDirective
来处理的。这使得在激活函数中使用 componentInstruction
来检查用户是否已登录变得容易,如果没有将他们重定向到我们的登录门户(出于各种原因,我无法通过单独的应用程序控制它,它具有它是自己的登录屏幕,然后在导航到下一个组件之前发回我们将保存在 Angular2 应用程序中的令牌。
我刚刚升级到路由器 3.0.0-alpha.8,我发现这不再是一个选项,它已被创建 authGuard 并使用 canActivate
方法处理身份验证所取代(我指的是 documentation 的这一部分)。我正在努力解决的问题是,这似乎是为只有少量路由受到保护的应用程序设计的,您只需将 canActivate: [AuthGuard]
添加到 RouterConfig 中需要身份验证的每个路由即可。
我遇到的问题是每条路由都需要通过身份验证来保护。还需要持续检查(除非有更好的解决方案),因为我们也会(部分原因是我们必须使用外部登录服务)注销用户并清除他们的令牌,下次您导航到新路线(无论路线是什么)它应该重定向您再次登录。我知道我可以将 canActivate: [AuthGuard]
添加到每条路线,但这似乎是一个疯狂而乏味的修复,特别是对于具有大量路线的应用程序,所有这些都需要用户经过身份验证才能查看。
我一直在寻找修复程序,但似乎(可能部分是因为升级是相当新的)所有资源都用于如何仅在一两个路由上实施这些 AuthGuard。我一直在挖掘源代码(特别是 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 调用中而不是在组件中提供这些服务(以及它们所依赖的服务等)。