【问题标题】:How can I return true/false based on api response message in my angular authguard method?如何在我的 angular authguard 方法中根据 api 响应消息返回真/假?
【发布时间】:2017-12-21 21:09:00
【问题描述】:

我已经放置了一个角度路由 authguard 来放置我的页面。我有一个 api 可以检查令牌是否有效,并基于此我想返回 true 或 false 以进行进一步导航。

但似乎在“订阅”中,我将“结果”标志设置为 true,而不是在订阅之外持续存在。这里的“结果”变量是否在错误的范围内?我该如何纠正?请帮助我理解我在以下代码中的错误。

canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
  const jwt = localStorage.getItem('jwt');
  let result = false;

  this.signinService.isSignedin(jwt).subscribe((res) => { // <---
    console.log(res.json().message);
    if (res.json().message === 'Token Valid') {
      result = true;
      console.log(result);
      return true;
    } else {
      result = false;
      return false;
    }
  }, (err) => { // <---
    console.log(err);
    result = false;
    return false;
  });
  console.log('END' + result);
  return result;}

上面的代码按以下顺序在控制台上打印出来,这对我来说似乎很奇怪。谁能解释一下?

END假

令牌有效

是的

【问题讨论】:

  • 你不能。这就是该方法也可以返回 Promise 或 Observable 的原因:这些类型允许返回一个布尔值异步。如果这样做,路由器将订阅返回的 observable/promise,并在发出布尔偶数时导航(或不导航)。
  • 嘿,任何答案对您有帮助吗? :)
  • 是的,这让我明白我不能从和 api 调用返回布尔值。因此,正如我在下面的评论中所述,现在我决定在 jwt 存在时执行此操作并相应地返回布尔值。只有当用户发布时,我才会在服务器端验证令牌。

标签: angular subscribe auth-guard


【解决方案1】:

但似乎在“订阅”中,我将“结果”标志设置为 true,而不会在订阅之外持续存在。

我认为您还没有完全理解解释器将如何阅读和评估这段代码。因为 JavaScript event loop 从不阻塞,解释器将到达订阅块,发出请求,然后继续执行订阅块之外的代码,而无需等待回复回来。这就是为什么首先打印“ENDfalse”的原因。然后响应进来,回调函数被执行,console.log(res.json().message); 打印“Token Valid”和 console.log(result); 返回真。

您可以解决此问题的一种方法可能是返回整个可观察对象,然后在您实际想要使用“结果”值的地方订阅(实际上您的 canActivate 函数签名表明您应该返回一个可观察的,而不是数据)。

canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
  const jwt = localStorage.getItem('jwt');
  return this.signinService.isSignedin(jwt);
}

【讨论】:

  • 我正在尝试根据我将重定向到正确页面的内容返回布尔值。现在我决定在 jwt 存在时这样做,并且只有在用户发布时才会在服务器端验证令牌。话虽如此,您的详细反馈帮助我了解了 JS 的非阻塞事件。谢谢!!
【解决方案2】:

在你定义的回调函数执行之前返回结果值。这是非常合乎逻辑的,因为回调是在 api 往返完成后调用的。

【讨论】:

    【解决方案3】:

    你不能从 subscribe 返回任何东西,但你可以做的是从你的守卫那里返回一个 Observable。

    正如其他人所指出的,这是异步的,因此控制台日志的顺序。你可以在这里阅读更多信息:How do I return the response from an Observable/http/async call in angular2?

    至于如何格式化你的代码,让我们如前所述返回一个 Observable:

    // add 'return' and use 'map' instead: 
    return this.signinService.isSignedin(jwt).map((res) => {
      if (res.json().message === 'Token Valid') {
        return true;
      } else {
        return false;
      }
    }, (err) => {
      return false;
    });
    

    【讨论】:

      猜你喜欢
      • 2011-05-18
      • 1970-01-01
      • 2020-09-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-09
      • 2011-02-04
      • 1970-01-01
      • 2022-11-11
      相关资源
      最近更新 更多