angular authguard 重定向到 /

angular authguard redirecting to /

我已经更改了我的 authguard 以在用户对象为空时获取它。我只是将令牌存储在存储中。我看到 console.log "role and user ok" 和正确的 url /member 但它总是将我重定向到 / 而不是 /member 在我的情况下。

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    if (this.authService.loggedin) {
      if (!this.authService.user) {
        console.log('get user')
        this.authService.getUser().pipe(first()).subscribe((result: any) => {
          console.log(result.user)
          if (route.data.roles && route.data.roles.indexOf(result.user.role.name) === -1) {
            console.log('wrong role')
            this.router.navigate(['/']);
            return false;
          } else {
            console.log('role and user ok')
            console.log(state.url)
            return true;
          }
        });
      } else {
        console.log(this.authService.user)
        console.log('user already set')
        if (route.data.roles && route.data.roles.indexOf(this.authService.user.role.name) === -1) {
          console.log('WRONG ROLE')
          this.router.navigate(['/']);
          return false;
        } else {
          console.log('user and role ok')
          return true;
        }
      }

    } else {
      console.log('redirect to login')
      this.router.navigate(['/login']);
      return false;
    }
  }

授权服务

 public isLoggedIn() {
    if (localStorage.getItem('token')) {
      return true;
    } else {
      return false;
    }
  }

getUser() {
    return this.http.get<any>(environment.apiUrl + '/user').pipe(
      tap(res => this.setSession(res))
    );
  }

谢谢

你的问题就在这里

this.authService.getUser().pipe(first()).subscribe((result: any) => {
          console.log(result.user)
          if (route.data.roles && route.data.roles.indexOf(result.user.role.name) === -1) {
            console.log('wrong role')
            this.router.navigate(['/']);
            return false;
          } else {
            console.log('role and user ok')
            console.log(state.url)
            return true;
          }
        });

您正在订阅管道,因此它是异步的,代码流不会等待到 return 并继续前进,并且找不到任何值 true 或 false。基本上摆脱 asyc subscribe 调用,你会没事的,这让我质疑你为什么首先要 pipe() 它。

canActivate 需要 return 一个布尔值或一个布尔值的 Observable。如果你需要在 canActivate 中执行一些异步操作,你需要 return observable。然后路由器会等到 observable return 的值在激活路由之前。否则 guard 在异步方法 returns.

之前就已经完成执行了

将 return 语句添加到 this.auth.getUser 并使用 map 而不是 subscribe。路由器现在将订阅 returned observable 并等待结果。

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
  if (this.authService.loggedin) {
    if (!this.authService.user) {
      console.log('get user')
      return this.authService.getUser().pipe(map((result: any) => {
        console.log(result.user)
        if (route.data.roles && route.data.roles.indexOf(result.user.role.name) === -1) {
          console.log('wrong role')
          this.router.navigate(['/']);
          return false;
        } else {
          console.log('role and user ok')
          console.log(state.url)
          return true;
        }
      }));
    } else {
      console.log(this.authService.user)
      console.log('user already set')
      if (route.data.roles && route.data.roles.indexOf(this.authService.user.role.name) === -1) {
        console.log('WRONG ROLE')
        this.router.navigate(['/']);
        return false;
      } else {
        console.log('user and role ok')
        return true;
      }
    }

  } else {
    console.log('redirect to login')
    this.router.navigate(['/login']);
    return false;
  }
}