【发布时间】:2019-03-15 07:17:36
【问题描述】:
我正在使用 JWT 令牌保护我的 Angular 6 应用程序。我有一个身份验证服务来保护 UI 元素:
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 元素按预期消失,但受保护的页面仍然存在,不会调用路由身份验证保护,并且仅路由到 login导航到其他页面时。
我尝试在isAuthenticated() authService 方法中进行路由,但这会导致无限循环。如何在调用 AuthGuard 之外自动路由到 login?
编辑
路由:
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 mentions,路由器不知道 UI 元素调用了 isAuthenticated() 方法,现在被隐藏了正在返回false,直到调用 AuthService 刷新方法并执行相同的检查。我很想知道当 UI 元素调用 isAuthenticated() 方法时让路由器知道导航到 login 的最佳方法?
编辑:我的工作解决方案:
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();
}
}),
);
}
【问题讨论】:
-
我们可以看到路由设置吗?
-
可能是因为
this.isTokenExpired没有正确设置。 -
@NimaHakimi 我已经添加了路由。
-
@Ploppy 不,不是这样,应用程序有一个刷新计时器,每分钟更新一次 JWT 令牌,它还会检查当前令牌并在无效时导航到登录。此外,它适用于 UI 元素,只是不会被路由到 /login 的任何东西访问。
-
哪一个是您的受保护组件?
标签: angular authentication jwt angular6 angular-routing