首页 文章

角度保护canActivate方法不适用于Observable <boolean>

提问于
浏览
0

我正在尝试在访问路由之前验证后端的令牌

这是我的身份验证服务:

export class AuthService {

  private registerUrl = 'http://127.0.0.1:3000/register';
  private loginUrl = 'http://127.0.0.1:3000/signin';
  private verifyTokenUrl = 'http://127.0.0.1:3000/v';

  constructor(private http: HttpClient) { }


  isLoggedIn() {
    if (!localStorage.getItem('token')) {
      console.log('false in isloggedin method');
      return false;
    }
    console.log('logged in, not verified yet');
    return true;
  }

  isTokenValid(token): Observable<boolean> {
    console.log('verifing');
    return this.http.post<any>(this.verifyTokenUrl, {token});
  }

  getToken() {
    return localStorage.getItem('token');
  }
}

守护:

export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService,
              private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    if (this.authService.isLoggedIn()) {
      const token = localStorage.getItem('token');
      this.authService.isTokenValid(token)
      .pipe(
        map(e => {
          if (e) {
            return true;
          } else {
            this.router.navigate(['/login']);
            return false;
          }
        }),
        catchError((err) => {
          this.router.navigate(['/login']);
          return of(false);
        })
      );
    } else {
      this.router.navigate(['/login']);
      return of(false);
    }
  }
}

似乎observable没有激活"like when you use the subscribe method"并且API中的代码没有't even run. The canActivate() suppose to accept an Observable as returned value. The guard will wait for the Observable to resolve and look at the value. If ' true'它将通过检查,否则(任何其他数据或抛出错误)将拒绝该路由 . 指这个answer

在我的情况下,应用程序停留在当前页面,并且也不会发布到服务器 . 还有一个类似的问题here,他们通过添加 .take(1) 解决了它,但在我的情况下它给出了一个错误 Property 'take' does not exist on type 'OperatorFunction<{}, boolean>'

这是我的验证API以防万一

//.........token verify
app.post('/v', (req, res) => {
    const {token} = req.body
    const payload = jwt.verify(token, 'secretKey' )
    console.log(payload);
    if (!payload) {
        return res.status(401).send(false)
    }
    res.status(200).send(true)
})

2 回答

  • 2

    你没有归还你的观察力:

    this.authService.isTokenValid(token)
      //...
    
    return this.authService.isTokenValid(token)
      //...
    
  • 1

    尝试实现你的路线守卫返回一个可观察的:

    export class AuthGuard implements CanActivate {
      constructor(private authService: AuthService,
        private router: Router) { }
    
      canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
        return Observable.create(observer => {
          if (this.authService.isLoggedIn()) {
            const token = localStorage.getItem('token');
            this.authService.isTokenValid(token)
              .pipe(
                map(e => {
                  if (e) {
                    observer.next(true);
                  } else {
                    this.router.navigate(['/login']);
                    observer.next(false);
                  }
                }),
                catchError((err) => {
                  this.router.navigate(['/login']);
                  observer.next(false);
                })
              );
          } else {
            this.router.navigate(['/login']);
            observer.next(false);
          }
        });
      }
    }
    

    另外,不要忘记在app.module中将拦截器实现为提供者:

    // your.module.ts
    // ...
    providers: [
      ...,
      AuthGuard
    ];
    

    在你想要守卫的路线上:

    // some route to guard
    { path: 'guarded-route', component: GuardedRouteComponent, canActivate: [AuthGuard] }
    

相关问题