Проверьте API токена носителя с помощью стека MEAN - PullRequest
0 голосов
/ 23 марта 2020

Я работаю над приложением angular и изо всех сил пытаюсь внедрить проверку токенов носителя API.

Процесс выглядит следующим образом:

  1. Authguard просит AuthService проверить локально сохраненный токен аутентификации
      canActivate(): boolean {
        if(this.AuthService.isAuthenticated()){
          return true;
        } else{
          this.router.navigate(['elsewhere/maybeToSwimmingPool']);
        }
      }
Вызов метода AuthService isAuthenticated, который будет извлекаться, если токен действителен от API
      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);
      }
API декодирует токен, проверяет, существует ли пользователь в базе данных и возвращает логическое значение
    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 не может асинхронно ждать наблюдаемого? Я действительно не знаю, что не так с моим кодом. Надеюсь, вы, ребята, сможете найти смертельную ошибку и дать мне совет относительно моего кода? Это мой первый шаг со средним стеком, и я приветствую каждый совет, критику:)

Хорошего дня, Элке Джонсон

1 Ответ

1 голос
/ 23 марта 2020

Вы используете асинхронный код в вашем CanActivate охраннике, поэтому вы не должны возвращать boolean, а вместо этого возвращать Observable<boolean>. Точно так же ваш метод isAuthenticated не должен вызывать subscribe, а вместо этого возвращать наблюдаемое. Причина, по которой ваш код не работает, заключается в том, что Guard не ожидает завершения всех блоков подписки до sh. Вместо этого Guard немедленно возвращает какое-то значение (синхронно), и проверка вашего токена происходит позже.

Я полагаю, что это сработает, если вы структурируете его следующим образом. Я не трогал ваш бэкэнд, хотя.

  1. В стороже вы возвращаете наблюдаемый результат, и если пользователь не аутентифицирован, выполните свой побочный эффект в операторе tap. Охрана подпишется на возвращаемое значение функции canActivate.
canActivate(): Observable<boolean> {
  return this.AuthService.isAuthenticated().pipe(
    tap( isAuthenticated => !isAuthenticated ?  this.router.navigate(['elsewhere/maybeToSwimmingPool']): 0)
  );

Здесь вместо подписки вы просто возвращаете наблюдаемое.

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);
}
...