【发布时间】:2017-07-31 23:01:29
【问题描述】:
我目前正在 angular2 中构建一个应用程序。因此,我实现了一个处理登录、注册等的 AuthService。
如果用户登录的 id_token (angular2-jwt) 存储在 localStorage 中。用户的角色和权限存储在AuthService.userRoles和AuthService.userPerms中。
布尔属性 AuthService.isAuthenticated 使用来自 angular2-jwt 的函数 tokenNotExpired(),如果用户退出或存储在 localStorage 中的令牌已过期,该函数将返回 false。如果用户登录AuthService.isAuthenticated更新为true;
我得到了使用 AuthGuard 的路由,它只允许 authenticated 用户通过检查 AuthService.isAuthenticated 属性来激活此路由。
如果某条路线如下所示:
{
path: "somewhere",
component: SomeComponent,
canActivate: [AuthGuard],
data: {
permissions: [
"add:some",
"edit:some"
]
}
}
相同的 AuthGuard 通过将AuthService.userPerms 与路由的data.permissions 匹配来检查当前登录用户是否具有所需的权限。 同样有效。
我的应用使用“主要组件”。这个主要组件是“公共的”并且不使用 AuthGuard。它在主 app.module 内部引导,并且没有自己的路线。在这个主要父组件的模板中,我得到了应用程序范围的导航。
此导航内部是路由按钮,这些按钮受 AuthGuard 保护,因此只有在用户登录并且具有某些权限或角色(如果路由需要)时才能访问。例如
<button [routerLink]="/somewhere">Somewhere</button>
如果用户点击此按钮并且未获得未授权,他将被重定向到unauthorized 路由。 工作至今
我想防止这种情况发生,方法是让这些按钮仅在用户能够激活路线时才可见。
<button [routerLink]="/somewhere"
*ngIf="isAuthorized["buttonSomewhere"]">
Somewhere
</button>
因此,在主 AppComponent(处理导航)中,我想检查模板内每个按钮的 userPermissions 并将结果存储在如下对象中:
/* AppComponent */
public isAuthorized = {
buttonSomewhere = true;
}
这个检查由AuthService.isAuthorized(theRouteToBeActivated)处理,它在AppComponent构造函数中被调用并将路由data.permission与存储在AuthService.userPerms中的用户权限相匹配。
问题是,由于 AppComponent 是 public 并且不受 AuthGuard 保护,因此构造函数在用户未登录时运行,这是正确的。此时被调用的AuthService.isAuthorized(theRouteToBeActivated)返回false并将值存储在
/* AppComponent */
public isAuthorized = {
buttonSomewhere = false;
}
这也是正确的。因此,如果用户退出,他将看不到他无法激活的路由按钮。
但问题是:在用户登录后,AppComponents 构造函数中调用的AuthService.isAuthorized(theRouteToBeActivated) 被不再次调用,并且
/* AppComponent */
public isAuthorized = {
buttonSomewhere = false;
}
保持原样。但是用户登录后需要再次调用该函数,使其返回true并发生变化
/* AppComponent */
public isAuthorized = {
buttonSomewhere = true;
}
以便模板中的按钮现在对登录用户可见。目前我需要在浏览器中重新加载应用程序。然后这些按钮对登录用户可见。但我不想重新加载。
我该如何解决这个问题?
【问题讨论】:
标签: angular authentication service angular2-jwt