使用 MEAN 堆栈验证持有者令牌 API

Verify bearer token API with the MEAN stack

我正在开发 angular 应用程序,但我很难实现 api 的不记名令牌验证。

过程如下所示:

  1. Authguard 要求 AuthService 验证本地存储的身份验证令牌
      canActivate(): boolean {
        if(this.AuthService.isAuthenticated()){
          return true;
        } else{
          this.router.navigate(['elsewhere/maybeToSwimmingPool']);
        }
      }
  1. AuthService 调用 isAuthenticated 方法,如果令牌有效,该方法将从 api
  2. 获取
      isAuthenticated(){
        if(localStorage.getItem('token')){
          this.verifyToken().subscribe(
            data => {return data;}
          )
        }else{
          return false;
        }
      }

      verifyToken() : Observable<boolean>{
        const url = this.apiVerifyTokenUrl + '/' + localStorage.getItem('token');
        return this.http.get<boolean>(apiVerifyTokenUrl, this.httpOptions);
      }
  1. Api 解码令牌,检查用户是否存在于数据库中,return 布尔值
    exports.verifyToken = (req, res, next) => {
     try{
      verifiedJwt = jwt.verify(req.params.token, secret);
      let userId= verifiedJwt.userId;
      User.findOne({_id: userId})
      .then(() => res.status(200).send('true'))
      .catch(error => res.status(200).send('false'));
     }
     catch(e){
      res.status(200).send('false');
     }
    }

我不确定我编写的是什么怪物。也许 Authguard 不能异步等待 observable? 我真的不知道我的代码有什么问题,我希望你们能找到致命的错误并给我建议我的代码?这些是我在 mean stack 上的第一步,我欢迎每一个建议,批评 :)

祝你有美好的一天, 埃尔克·约翰逊

您正在 CanActivate 守卫中使用异步代码,因此您不应该 return boolean,而是 return Observable<boolean>。同样,您的 isAuthenticated 方法不应调用 subscribe,而应调用 return 一个可观察对象。您的代码不起作用的原因是 Guard 不会等待所有订阅块完成。相反,Guard 会立即 return 一些值(同步地)并且您的令牌检查会在稍后发生。

我想如果你这样构建它会起作用。我没有碰你的后端。

  1. 在守卫中 return 结果的可观察性,如果用户未通过身份验证,则在 tap 运算符中产生副作用。守卫将订阅 canActivate 函数的 return 值。
canActivate(): Observable<boolean> {
  return this.AuthService.isAuthenticated().pipe(
    tap( isAuthenticated => !isAuthenticated ?  this.router.navigate(['elsewhere/maybeToSwimmingPool']): 0)
  );

这里不是订阅,你只是 return 一个可观察的。

isAuthenticated(): Obsevable<boolean>{
  const token = localStorage.getItem('token');
  if(token){
     return this.verifyToken(token)
  }
}

verifyToken(token) : Observable<boolean>{
  const url = this.apiVerifyTokenUrl + '/' + token
  return this.http.get<boolean>(apiVerifyTokenUrl, this.httpOptions);
}