1

我想对某些路由的每个刷新请求进行一些验证。所以我正在使用 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调用不起作用并将通过。我的意思是从本地存储检查它的第一部分工作正常。但是下一部分用在线 API 检查它是行不通的。并且authGuard不等待它的响应来进行路由。

我想它应该以某种async/await方式。但是我做了一些测试,但都没有奏效。如果有人可以帮助我,我会很高兴。

4

1 回答 1

2

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);
    })
  );

}

这是您的参考的工作演示

于 2019-12-22T06:23:04.790 回答