canActivate должен дождаться логического значения этого.AuthService.isLoggedIn

#angular #typescript #authentication #angular-route-guards

Вопрос:

Я хочу, чтобы мое приложение направлялось домой:»», когда пользователь входит в систему со своей электронной почтой Google. Все работает, кроме canActivate routeGuard. this.authService.isLoggedIn возвращает false после того, как я попытаюсь перейти к «» во время функции AuthLogin. После входа в систему routeguard перенаправляет на «вход», а не на «», если я попытаюсь сразу перейти на»», это сработает, потому this.authService.isLoggedIn что в console.log отображается значение true. Так что, похоже, canActivate нуждается в способе дождаться this.authService.isLoggedIn обновлений, есть идеи?

модуль маршрутизации приложений:

 import { AuthGuard } from "./shared/guard/auth.guard";

const routes: Routes = [
  { path: "", component: HomeComponent, canActivate: [AuthGuard] },
  { path: "login", component: LoginComponent },
  { path: "results", component: ResultsComponent },
  { path: "profile", component: ProfileComponent },
  // otherwise redirect to home
  { path: "**", redirectTo: "" },
];
 

авторизационная служба:

 // Returns true when user is looged in and email is verified
  get isLoggedIn(): boolean {
    const user = JSON.parse(localStorage.getItem("user"));
    return user !== null amp;amp; user.emailVerified !== false ? true : false;
  }

  googleLogin() {
    return this.AuthLogin(new firebase.auth.GoogleAuthProvider());
  }

  async AuthLogin(provider: firebase.auth.AuthProvider) {
    try {
      const result = await this.afAuth.auth.signInWithPopup(provider);
      this.SetUserData(result.user);
      this.router.navigate([""]);
    } catch (error) {
      window.alert(error);
    }
  }

  SetUserData(user) {
    const userRef: AngularFirestoreDocument<any> = this.afs.doc(`users/${user.uid}`);
    const userData: User = {
      uid: user.uid,
      email: user.email,
      displayName: user.displayName,
      photoURL: user.photoURL,
      emailVerified: user.emailVerified,
    };
    return userRef.set(userData, {
      merge: true,
    });
  }
 

авт.охранник:

 import { AuthService } from "src/app/services/auth/auth.service";

@Injectable({
  providedIn: "root",
})
export class AuthGuard implements CanActivate {
  constructor(public authService: AuthService, public router: Router) {}
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    console.log(this.authService.isLoggedIn);
    if (this.authService.isLoggedIn !== true) {
      this.router.navigate(["login"]);
    }
    return true;
  }
}
 

Комментарии:

1. Ваш AuthGuard проверяет наличие функции isLoggedIn в вашей службе аутентификации, в которой ему нужен пользователь localStorage. Теперь проблема в том, что, основываясь на опубликованном вами коде, я не вижу в вашей функции входа в Google, где вы устанавливаете пользователя localStorage.

Ответ №1:

Вам нужно настроить обещание для SetUserData того userRef , чтобы оно зависело от запроса Firestore. После того, как обещание будет выполнено, перейдите к "" .