首页 > 解决方案 > 带有可观察令牌的 Angular CanActivate 不等待

问题描述

我知道有几个线程,我确实尝试了每一个解决方案,但我不确定我的情况有什么不同。

我想创建一个 Guard 来访问视图以在服务器验证令牌后更改密码。

   canActivate(
     route: ActivatedRouteSnapshot,
     router: RouterStateSnapshot
   ):
     | Observable<boolean | UrlTree>
     | Promise<boolean | UrlTree>
     | boolean
     | UrlTree {
     const queryString = window.location.search;
     const urlParams = new URLSearchParams(queryString);
     if (urlParams.has("token")) {
       let token = urlParams.get("token");
       this.authService.getResetPasswordPermission(token).subscribe(
         (res) => {
           return true;
         },
         (err) => {
           return false;
         }
       );
     } else {
       return this.router.createUrlTree(["/authenticate"]);
     }
   }

我知道订阅不会等待结果,所以return this.router.createUrlTree(["/authenticate"]);会被执行。我尝试使用mappipe但它永远不会进入该方法的结果,所以也没有resor err

不知何故,我总是会被重定向到 localhost:4200 而不是 localhost:4200/changePassword 我想去的地方,甚至是 localhost:4200/authenticate 我应该登陆的地方。

与服务器对话的 Observable 方法如下所示:

   getResetPasswordPermission(token): Observable<any> {
     let data = { token: token };
     return this.http.get<any>(RESET_PASSWORD_PERMISSION_API, { params: data });
   }

如果成功,答案是ResponseEntity.ok(token).

如果没有ResponseEntity.badRequest()。我知道它们的语法都不正确,但你明白我的意思。

如果我将登陆 changePassword 页面,则需要再次使用该令牌将其与更改请求一起发送。

标签: angular

解决方案


我知道您已经尝试过,但我认为地图运算符适合您的情况。尝试这样的事情:

canActivate(
     route: ActivatedRouteSnapshot,
     router: RouterStateSnapshot
   ):
     | Observable<boolean | UrlTree>
     | Promise<boolean | UrlTree>
     | boolean
     | UrlTree {
     const queryString = window.location.search;
     const urlParams = new URLSearchParams(queryString);
     if (urlParams.has("token")) {
       let token = urlParams.get("token");
       return this.authService.getResetPasswordPermission(token).pipe(
          catchError(err => return of(null)),
          map(resp => !!resp)
       );
     } else {
       return this.router.createUrlTree(["/authenticate"]);
     }
   }

推荐阅读