我用JWT令牌保护我的角6应用程序。我有一个保护UI元素的auth服务:
export class AuthService {
constructor(
private http: HttpClient,
private router: Router,
public jwtHelper: JwtHelperService,
) {}
isAuthenticated(): boolean {
return !this.isTokenExpired;
}然后我可以调用我的组件:
<span class="page-nav" *ngIf="!authService.isAuthenticated()">
<a mat-button routerLink="/login">
Log In
</a>
</span>我也有一个守卫我的路线:
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(): boolean {
if (!this.authService.isAuthenticated()) {
this.router.navigate(['/login']);
return false;
}
return true;
}
}这一切都很好,除非令牌变得无效,否则当前页面不会路由到login。
例如,如果我登录,获得一个有效的JWT令牌,我可以导航到受保护的页面,并显示受保护的UI元素(导航等等)。如果我然后通过chrome工具从本地存储中删除JWT令牌,然后单击导航,受保护的UI元素就会如预期的那样消失,但是受保护的页面将保持不变,路由auth保护不会被调用,只会在导航到另一个页面时将路由路由到login。
我尝试过在isAuthenticated() authService方法中路由,但这会导致无限循环。如何在调用login之外自动路由到AuthGuard?
编辑
路由:
const routes: Routes = [
{ path: '', redirectTo: '/products', pathMatch: 'full' },
{
path: 'products',
component: ProductsComponent,
canActivate: [AuthGuard],
children: [
{ path: ':id', component: ProductComponent, canActivate: [AuthGuard] },
],
},
{
path: 'search',
component: SearchComponent,
canActivate: [AuthGuard],
},
{ path: 'login', component: LoginComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}编辑:我意识到这是预期的行为,作为@GangadharJannu 提及,路由器不知道UI元素已经调用了isAuthenticated()方法,并且在返回false时隐藏起来,直到调用AuthService刷新方法并执行相同的检查。我想知道当UI元素调用login方法时,让路由器知道导航到isAuthenticated()的最佳方法是什么?
编辑:我的工作解决方案:
import { map } from 'rxjs/operators';
import { interval } from 'rxjs';
import { JwtHelperService } from '@auth0/angular-jwt';
...
public validateToken(): void {
interval(1000).pipe(
map(() => {
const isExpired: boolean = this.jwtHelper.isTokenExpired(
localStorage.getItem('jwt_token'),
);
if (isExpired) {
this.logout();
}
}),
);
}发布于 2018-10-10 12:42:29
我们的父级空状态只是为了保护应用程序的受保护部分,您可能需要尝试一下。尝试如下所示的路由配置:
const routes: Routes = [{
path: '',
canActivateChild: [AuthGuard],
runGuardsAndResolvers: 'always',
children: [{
path: 'products',
component: ProductsComponent,
children: [
{ path: ':id', component: ProductComponent },
],
}, {
path: 'search',
component: SearchComponent
}]
},
{ path: '', redirectTo: '/products', pathMatch: 'full' },
{ path: 'login', component: LoginComponent },
];注意runGuardsAndResolvers: 'always' -它告诉角总是运行警卫和解析器,即使在导航到相同的状态。
编辑
因此,基本上您希望观察本地存储并对更改作出反应,因此,当令牌从存储中移除或过期时,您希望立即导航到登录组件。一些想法:
https://stackoverflow.com/questions/52739186
复制相似问题