简体   繁体   中英

Angular AuthGuard CanActivate not called when signing out - Firebase Auth

The AuthGuard CanActivate is called correctly after login and the user is redirected to route they came from. The issue only arises when the user signs out, the CanActivate doesn't seem to be triggered

AuthGuard

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> {
    return this.checkLogin(state.url);
  }

  checkLogin(url: string): Observable<boolean> {
    // Store the attempted URL for redirecting
    this.authService.redirectUrl = url;
    return this.authService.isAuthenticated.pipe(
      tap(auth => (!auth ? this.router.navigate(['login']) : true))
    );
  }
}

AuthService

  get isAuthenticated(): Observable<boolean> {
    return this.angularFireAuth.authState.pipe(
      take(1),
      map(authState => !!authState)
    );
  }

app routes

export const AppRoutes: Routes = [
  { path: "", redirectTo: "dashboard", pathMatch: "full" },
  { path: "login", component: LoginComponent },
  {
    path: "dashboard",
    component: DashboardComponent,
    canActivate: [AuthGuard]
  },
  { path: "trades", component: TradeComponent, canActivate: [AuthGuard] },
  { path: "profile", component: ProfileComponent, canActivate: [AuthGuard] }
];

@NgModule({
  imports: [RouterModule.forRoot(AppRoutes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

adding that.router.navigate(['login']) to logout() works but this feels like a hack as AuthGuard isn't triggered.

  logout(): void {
    var that = this;
    this.angularFireAuth.auth.signOut().then(function() {
      localStorage.clear();
      that.router.navigate(['login']);
    });
  }

One thing I can think of is that this.angularFireAuth.authState is not changed on logout and therefore doesn't trigger the AuthGuard. Meaning if I had isAuthenticated() return a simple boolean which set to false during logout, the AuthGuard would trigger

I think you should remove take(1) from:

return this.angularFireAuth.authState.pipe(
    take(1),
    map(authState => !!authState)
);  

With take(1) you will receive data from observable only once (when you log in).

i don't see that you added you guard to providers array in AppModule , and this may solve your problem.

@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'dashboard', 
        component: DashboardComponent,
        canActivate:[AuthGuard],
      }
    ])
  ],
  providers: [AuthGuard]
})
class AppModule {}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM