我目前正在 angular2 中构建一个应用程序。因此,我实现了一个处理登录、注册等的 AuthService。如果用户登录 id_token (angular2-jwt) 存储在 localStorage 中。用户的角色和权限存储在AuthService.userRoles
和中AuthService.userPerms
。
布尔属性AuthService.isAuthenticated
使用tokenNotExpired()
来自 angular2-jwt 的函数,如果用户退出或存储在 localStorage 中的令牌已过期,该函数将返回 false。如果登录的用户AuthService.isAuthenticated
更新为true
;
我得到了使用 AuthGuard 的路由,它只允许经过身份验证AuthService.isAuthenticated
的用户通过检查属性来激活此路由。
如果某条路线如下所示:
{
path: "somewhere",
component: SomeComponent,
canActivate: [AuthGuard],
data: {
permissions: [
"add:some",
"edit:some"
]
}
}
相同的 AuthGuard 通过AuthService.userPerms
与路由的 data.permissions
. 这也有效。
我的应用程序使用“主要组件”。这个主要组件是“公共的”并且不使用AuthGuard。它在 main 内部自举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 是公共的并且不受 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;
}
这样模板中的按钮现在对登录用户可见。目前我需要在浏览器中重新加载应用程序。然后这些按钮对登录用户可见。但我不想重新加载。
我怎么能解决这个问题?