Angular7 AuthGuard Firebase Заявления - PullRequest
0 голосов
/ 22 марта 2019

Я могу войти через firebase, но в моем приложении 3 уровня пользователей. Давайте назовем их администратором, пользователем, редактором. Я сохраняю роль пользователя в пользовательских требованиях, предоставленных Firebase.

В AuthGuard я передаю данные expectedRoles = ['admin', 'editor'], добавляя роли, которые я хочу разрешить для определенного маршрута. И я хочу сделать перенаправление на свою страницу, например редактор, пытающийся направить администратора, будет возвращен на панель редактора.

Это функция canActivate моего AuthGuard:

return this.auth.user.pipe(
  map(user => {
    if (user) {
      user.getIdTokenResult().then((idTokenResult) => {
        if (idTokenResult.claims.admin) {
          if (expectedRoles.indexOf('admin') > -1) {
            return true;
          } else {
            // return back to admin dashboard
            this.router.navigate(['/admin']);
          }
        } else if (idTokenResult.claims.editor) {
          if (expectedRoles.indexOf('editor') > -1) {
            return true;
          } else {
            // return back to editor dashboard
            this.router.navigate(['/editor']);
          }
        } else if (idTokenResult.claims.user) {
          if (expectedRoles.indexOf('user') > -1) {
            return true;
          } else {
            // return back to user dashboard
            this.router.navigate(['/user']);
          }
        } else {
          // Unexpected claim, better logout, TODO; display something
          this.router.navigate(['/auth/logout']);
        }
      });
    } else {
      // User is not authenticated
      // Check if we are expecting a guest
      if (expectedRoles.indexOf('guest') > -1) {
        return true;
      } else {
        this.router.navigate(['/auth/login']);
      }
    }
  })
).first();

Перед добавлением user.getIdTokenResult().then(...) все работало нормально, и я знаю, что это, вероятно, связано с не ожиданием асинхронного вызова для анализа пользовательских утверждений. Как я могу обойти это?

Ответы [ 2 ]

2 голосов
/ 22 марта 2019

Используйте switchMap вместо карты, сделайте функцию async и дождитесь результата.switchMap принимает обещание, возвращаемое функцией async.Тогда внутри вы можете использовать await.

return this.auth.user.pipe(
  // switchMap instead of map
  // async function call
  switchMap(async (user) => {
    if (user) {
      // await here
      await user.getIdTokenResult().then((idTokenResult) => {
        if (idTokenResult.claims.admin) {
          if (expectedRoles.indexOf('admin') > -1) {
            return true;
          } else {
            // return back to admin dashboard
            this.router.navigate(['/admin']);
          }
        } else if (idTokenResult.claims.editor) {
          if (expectedRoles.indexOf('editor') > -1) {
            return true;
          } else {
            // return back to editor dashboard
            this.router.navigate(['/editor']);
          }
        } else if (idTokenResult.claims.user) {
          if (expectedRoles.indexOf('user') > -1) {
            return true;
          } else {
            // return back to user dashboard
            this.router.navigate(['/user']);
          }
        } else {
          // Unexpected claim, better logout, TODO; display something
          this.router.navigate(['/auth/logout']);
        }
      });
    } else {
      // User is not authenticated
      // Check if we are expecting a guest
      if (expectedRoles.indexOf('guest') > -1) {
        return true;
      } else {
        this.router.navigate(['/auth/login']);
      }
    }
  })
).first();

Просто подсказка, не связанная с этим решением - лучше, чем загружать токен в функцию AuthGuard, вы должны загрузить его после того, как пользователь войдет в систему и сохранитэто в магазине так же, как вы храните информацию из ответа входа в систему.Это будет намного быстрее.

0 голосов
/ 22 марта 2019

Попробуйте использовать каналы rxjs для внутренних наблюдаемых вызовов: flatMap и flatMapTo или mergeMap или mergeMapTo.В вашем конкретном случае я думаю, что MergeMap - это путь.

Не стесняйтесь читать об этих каналах в rxjs, они могут быть решением

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...