【问题标题】:AuthGuard wait for API callAuthGuard 等待 API 调用
【发布时间】:2021-05-05 01:19:40
【问题描述】:

我正在尝试阻止非管理员用户访问管理仪表板本身。为此,我必须在后端检查令牌是否有效,如果有效,则用户实际上是管理员。我似乎能够阻止它,但我不知道如何在 Angular 11 的 AuthGuard 中等待 API 调用?我必须使 canActivate() 方法异步还是什么?

身份验证服务:

  // This method works and returns an Observable<boolean>
  public hasUserRole(theAccessToken: string, userRole: string): Observable<any> {
    const httpOptions = {
      headers: new HttpHeaders({
        accessToken: theAccessToken,
        requiredUserRole: userRole,
      })
    };
    return this.http.get<any>(Constants.API_ENDPOINT_GET_USER_ROLES, httpOptions);
  }

  // This method, I don't know how to implement... I tried .pipe and .tap and whatnot but I can't get anything to wait for the API call to finish.
  public isLoggedInAndHasUserRole(token: string, userRole: string): boolean {
      // return this.hasUserRole(token, userRole); // TODO: How to wait for this API call? .map doesn't seem to work in Angular11 and I can't get the .pipe() to work either.
  }

Auth Guard(有效,但我不知道如何等待 API 调用):

public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    const token = this.commonService.getToken();

    if (token !== '' && token !== undefined) {

      if (this.authenticationService.isLoggedInAndHasUserRole(token, 'Admin')) {
<snip for brevity>

带有 API 结果的图像

【问题讨论】:

    标签: angular api asynchronous angular11


    【解决方案1】:

    canActivate has several return values. 你可以返回Observable&lt;boolean&gt; 并且auth 守卫只会在该可观察对象被解决后继续。

    public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> {
        const token = this.commonService.getToken();
    
        if (token !== '' && token !== undefined) {
            return this.authenticationService.isLoggedInAndHasUserRole(token, 'Admin').pipe(
            map((hasRole) => {
                if (hasRole) {
                    return true;
                } else {
                    this.commonService.navigateToHome();
                    return false; //
                }
            }));
        } else {
           this.commonService.navigateToLogin();
           return false;
        }
    }
    

    在您的授权服务中:

     public isLoggedInAndHasUserRole(token: string, userRole: string): Observable<boolean> {
          return this.hasUserRole(token, userRole);
      }
    

    【讨论】:

    • 在这种情况下我将如何实现 isLoggedInAndHasUserRole() ?如果我使用 .subscribe(),它总是会返回 false 并且 AuthGuard 不会等待。
    • 无需订阅任何内容。如果您的 API 端点返回一个布尔值,那么您当前的代码应该可以工作
    • isLoggedInAndHasUserRole() 是空的,甚至不能编译,因此它不可能工作......我错过了什么?还是您的意思是另一种方法(我的 AuthGuard 不等待)?您能否在您的答案中也包含服务代码?
    • API_ENDPOINT_GET_USER_ROLES 的返回值是多少?一系列角色?如果是,那么 isLoggedInAndHasUserRole 应该返回以下内容:return this.hasUserRole(token, userRole).pipe(map((userRoles) =&gt; { return userRoles.find(r =&gt; r === userRole) }));
    • 这是一个常量字符串,值为:localhost:<snip>/api/token/hasUserRole
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-15
    • 2019-03-25
    • 2021-05-12
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 2018-03-31
    相关资源
    最近更新 更多