问题
I want to do some validation on each refresh request for some routes. So I'm using Angular AuthGuard
. The problem is in canActivate
method I want to perform validation with online API.
API is /token/verify
which simply gets token
variable (jwt) and verify if it's true or false.
Then if verify is not complete will route to /login
page else do the rest.
Here is the code:
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;
})
and the verifyToken
method is like this:
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
});
}
Problem is that the promise
call doesn't work and will be passed. I mean the first part that does check it from localstorage works fine. But the next part that checks it with online API will not work. and authGuard
doesn't wait for its response to do the routing.
I guess it should be in some async/await
manner. But I did some tests and none of them worked. Will be glad if anyone could help me.
回答1:
I think you'll be able to simplify the whole implementation if you use Observable
s instead.
If you do consider that proposal, then your verifyToken
method could be refactored to this:
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)
}
And then in your Guard, you'd simply do this:
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.
来源:https://stackoverflow.com/questions/59442021/verify-token-with-api-in-angular8-canactivate-method-of-authguard