angular 2 Auth警卫打破重定向

时间:2017-03-11 12:19:51

标签: angular angular2-routing

这是我的app-routing.module.ts

const routes: Routes = [
  { path: '', redirectTo: '/app/elements', pathMatch: 'full' },
  {path: 'app', component:ElementsComponent, children:[
    { path: 'details/:id', component: ElementDetailComponent, canActivate:[AuthGuard]},
    { path: 'elements',     component: ElementListComponent, canActivate:[AuthGuard] },

    { path: 'user/signup',     component: SignupComponent },
    { path: 'user/login',     component: LoginComponent },
    { path: 'user/logout',     component: LogoutComponent }
  ]}

];
@NgModule({
  imports: [ RouterModule.forRoot(routes) ],
  exports: [ RouterModule ],
  providers: [AuthGuard]
})
export class AppRoutingModule {}

正如您所看到的路径''我正在重定向到/app/elements这是我的主页。这工作正常,直到我实现AuthGuard看起来像:

@Injectable()
export class AuthGuard implements CanActivate{

  public allowed: boolean;

  constructor(private af: AngularFire, private router: Router) { }


  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    this.af.auth.subscribe((auth) =>  {
      if(auth == null) {
        this.router.navigate(['/app/user/login']);
        this.allowed = false;
      } else {
        this.allowed = true;
      }
    });
    return this.allowed;
  }
}

现在,如果用户未登录并转到http://localhost:4200/,则重定向会起作用并尝试转到http://localhost:4200/app/elements,警卫会检测到用户未登录并重定向到登录页面。

问题是如果用户 已登录并尝试转到http://localhost:4200/。在这种情况下,没有任何反应,用户停留在该URL并且页面空白。

为什么重定向在这种情况下不起作用?有办法解决这个问题吗?

2 个答案:

答案 0 :(得分:4)

canActivatefirebase observable结算之前返回,因此canActivate将始终返回false,但canActivate可以返回promise或Observable。

应该有效:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.af.auth
                  .map(auth => auth != null)      // null means not authenticated
                  .do(isAuthenticated => {   // change routes if not authenticated
                     if(!isAuthenticated) {
                       this.router.navigate(['/app/user/login']);
                     }
                  });

}

答案 1 :(得分:0)

您可以使用保持身份验证状态的服务。之后,只使用没有订阅的代码。因为它执行了异步并制动代码。

public canActivate() {      
    if (this.authService.isAuthenticated) 
      return true;
    this.router.navigate(['/app/user/login']);
    return false;
}