我正在尝试添加一个Route Guard,它将把JWT发送到PHP API,该API将返回true或false,具体取决于用户是否通过了身份验证。通过我的测试,Route Guard一直工作到它实际调用API为止。如果API返回false,则防护措施将按预期工作。但是,如果API返回true,则防护罩似乎要重定向用户,就好像它返回false一样,但是它不显示主屏幕,而是不显示任何内容。
auth.guard.ts
canActivate(): boolean {
if (localStorage.getItem('portfolioJWT') === null) {
this.router.navigate(['/']);
return false;
} else {
const token = JSON.parse(localStorage.getItem('portfolioJWT'));
this.authService.isAuth(token).subscribe(res => {
console.log(res);
if(!res) {
this.router.navigate(['/']);
console.log("NOT Authorized");
return false;
} else {
console.log("Authorized");
return true;
}
});
}
}
auth.service.ts
isAuth(token: string): Observable<Boolean> {
const authHttpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + token
})
};
return this.http.post<Boolean>('http://portfolioapi/api/checkAuth', {}, authHttpOptions);
}
我让防护控制台记录了返回的值,以及是否对用户进行了授权,并记录了正确的数据。
答案 0 :(得分:1)
问题可能是您没有为canActivate使用Promise<boolean>
,因此当canActivate仍在后台执行时,
路由器已经继续运行,从而触发了意外行为。
一个例子可能是API返回false
并初始化navigate
,但仅在路由器已经导航到您的某个地方之后(可能会触发空白页面),API才返回。 console.log(res)
也是如此。可能可行,但为时已晚,路由器已启动。
您想要实现的是路由应该暂停,直到收到true或false为止。在没有Promise的情况下检查局部变量的值可能会很好地工作,但是在执行API调用时确实很重要,因为它是 asynchronous ,因此您明确需要告诉路由器等待通话结束。
canActivate(): Promise<boolean> {
return new Promise((resolve) => {
if (localStorage.getItem('portfolioJWT') === null) {
this.router.navigate(['/']);
resolve(false);
} else {
const token = JSON.parse(localStorage.getItem('portfolioJWT'));
this.authService.isAuth(token).subscribe(res => {
console.log(res);
if(!res) {
this.router.navigate(['/']);
console.log("NOT Authorized");
resolve(false)
} else {
console.log("Authorized");
resolve(true)
}
});
}
})
}