在 AuthGuard 的 Angular8 canActivate 方法中使用 API 验证令牌
Verify token with API in Angular8 canActivate method of AuthGuard
我想对某些路由的每个刷新请求进行一些验证。所以我使用 Angular AuthGuard
。问题出在 canActivate
方法中,我想使用在线 API 执行验证。
API 是 /token/verify
,它只是获取 token
变量 (jwt) 并验证它是对还是错。
然后,如果验证未完成,将路由到 /login
页面,否则执行其余操作。
代码如下:
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
let token = this.auth.getToken();
let url = '/token/verify/';
if (!token) {
this.router.navigate(['/login']);
return false;
}
this.auth.verifyToken().then(res => {
return true;
}).catch(err => {
this.router.navigate(['/login']);
return false;
})
而verifyToken
方法是这样的:
verifyToken(): Promise<boolean> {
let token = this.getToken();
return !token ?
new Promise<boolean>(resolve => {
resolve(false);
return false;
}) :
this.http.post(this.url + '/token/verify/', { 'token': token })
.toPromise()
.then((res) => {
localStorage.data = JSON.stringify(res);//(res.json());
return true;
}
).catch((error) => {
return false
});
}
问题是promise
调用不通,将通过。我的意思是从 localstorage 检查它的第一部分工作正常。但是接下来用在线 API 检查它的部分将不起作用。并且 authGuard
不等待其响应进行路由。
我想它应该是某种 async/await
方式。但我做了一些测试,其中 none 有效。如果有人能帮助我,我会很高兴。
我认为如果改用 Observable
s,您将能够简化整个实施。
如果您确实考虑了该提案,那么您的 verifyToken
方法可以重构为:
import { of, Observable } from 'rxjs';
verifyToken(): Observable<boolean> {
const token = this.getToken();
return token ? this.http
.post(this.url + '/token/verify/', {
'token': token
})
.pipe(
tap(res => localStorage.data = JSON.stringify(res)),
map(
res => true,
error => false
)
) : of(false)
}
然后在您的 Guard 中,您只需执行以下操作:
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable < boolean > | Promise < boolean > | boolean {
const token = this.auth.getToken();
const url = "/token/verify/";
if (!token) {
this.router.navigate(['/login']);
return false;
}
return this.auth.verifyToken().pipe(
catchError(err => {
console.log('Handling error locally and rethrowing it...', err);
this.router.navigate(['/login']);
return of(false);
})
);
}
Here's a Working Demo for your ref.
我想对某些路由的每个刷新请求进行一些验证。所以我使用 Angular AuthGuard
。问题出在 canActivate
方法中,我想使用在线 API 执行验证。
API 是 /token/verify
,它只是获取 token
变量 (jwt) 并验证它是对还是错。
然后,如果验证未完成,将路由到 /login
页面,否则执行其余操作。
代码如下:
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
let token = this.auth.getToken();
let url = '/token/verify/';
if (!token) {
this.router.navigate(['/login']);
return false;
}
this.auth.verifyToken().then(res => {
return true;
}).catch(err => {
this.router.navigate(['/login']);
return false;
})
而verifyToken
方法是这样的:
verifyToken(): Promise<boolean> {
let token = this.getToken();
return !token ?
new Promise<boolean>(resolve => {
resolve(false);
return false;
}) :
this.http.post(this.url + '/token/verify/', { 'token': token })
.toPromise()
.then((res) => {
localStorage.data = JSON.stringify(res);//(res.json());
return true;
}
).catch((error) => {
return false
});
}
问题是promise
调用不通,将通过。我的意思是从 localstorage 检查它的第一部分工作正常。但是接下来用在线 API 检查它的部分将不起作用。并且 authGuard
不等待其响应进行路由。
我想它应该是某种 async/await
方式。但我做了一些测试,其中 none 有效。如果有人能帮助我,我会很高兴。
我认为如果改用 Observable
s,您将能够简化整个实施。
如果您确实考虑了该提案,那么您的 verifyToken
方法可以重构为:
import { of, Observable } from 'rxjs';
verifyToken(): Observable<boolean> {
const token = this.getToken();
return token ? this.http
.post(this.url + '/token/verify/', {
'token': token
})
.pipe(
tap(res => localStorage.data = JSON.stringify(res)),
map(
res => true,
error => false
)
) : of(false)
}
然后在您的 Guard 中,您只需执行以下操作:
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable < boolean > | Promise < boolean > | boolean {
const token = this.auth.getToken();
const url = "/token/verify/";
if (!token) {
this.router.navigate(['/login']);
return false;
}
return this.auth.verifyToken().pipe(
catchError(err => {
console.log('Handling error locally and rethrowing it...', err);
this.router.navigate(['/login']);
return of(false);
})
);
}
Here's a Working Demo for your ref.