【问题标题】:Angular AuthGuard CanActivate not called when signing out - Firebase Auth退出时未调用Angular AuthGuard CanActivate - Firebase Auth
【发布时间】:2019-05-03 18:42:24
【问题描述】:

登录后正确调用 AuthGuard CanActivate,并将用户重定向到他们来自的路由。该问题仅在用户退出时出现,CanActivate 似乎没有被触发

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

身份验证服务

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

应用路线

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 {}

将 that.router.navigate(['login']) 添加到 logout() 是可行的,但这感觉就像是黑客攻击,因为没有触发 AuthGuard。

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

我能想到的一件事是 this.angularFireAuth.authState 在注销时不会更改,因此不会触发 AuthGuard。这意味着如果我让 isAuthenticated() 返回一个在注销期间设置为 false 的简单布尔值,则 AuthGuard 将触发

【问题讨论】:

  • 顾名思义,它适用于[Activate],而不是[deActivate]。如果要停用,则需要设置[CanDeactivate] 警卫。

标签: angular firebase firebase-authentication google-cloud-firestore


【解决方案1】:

我没有看到您在AppModule 中将您的保护添加到提供程序数组中,这可能会解决您的问题。

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

【讨论】:

    【解决方案2】:

    我认为您应该从以下位置删除 take(1)

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

    使用 take(1),您只会从 observable 收到一次数据(当您登录时)。

    【讨论】:

    • 我尝试了使用 take(1) 和没有,它没有帮助。我添加了 take(1),因为有人建议 observable 需要结束才能使 AuthGuard 工作,否则它将被卡住。
    猜你喜欢
    • 2017-05-09
    • 1970-01-01
    • 2018-11-16
    • 2017-11-25
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 2017-10-15
    • 2016-11-06
    相关资源
    最近更新 更多