【问题标题】:Angular guard canActivate method dont work with Observable<boolean>Angular 防护 canActivate 方法不适用于 Observable<boolean>
【发布时间】:2019-04-30 19:39:08
【问题描述】:

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

这是我的身份验证服务:

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 没有“像使用 subscribe 方法一样”激活,并且 API 中的代码甚至没有运行。 canActivate() 假设接受一个 Observable 作为返回值。守卫将等待 Observable 解析并查看值。如果为“真”,它将通过检查,否则(任何其他数据或抛出的错误)将拒绝路由。指这个answer

在我的例子中,应用程序停留在当前页面,不会路由到目标,也不会发布到服务器。还有一个类似的问题here,他们通过添加.take(1) 解决了这个问题,但在我的情况下,它给出了一个错误Property 'take' does not exist on type 'OperatorFunction&lt;{}, boolean&gt;'

这是我的验证 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)
})

【问题讨论】:

    标签: angular authentication jwt angular7


    【解决方案1】:

    你没有返回你的 observable:

    this.authService.isTokenValid(token)
      //...
    

    —>

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

    【讨论】:

      【解决方案2】:

      尝试实现你的路由守卫返回一个 observable:

      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] }
      

      【讨论】:

      • 确实没有理由以这种方式创建 observable。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-22
      • 1970-01-01
      • 2020-08-02
      • 2017-11-25
      • 2020-10-17
      相关资源
      最近更新 更多