我试图使用Firebase Auth构建一个角色2路由的AuthGuard.
这是AuthGuard服务:
import { Injectable } from '@angular/core'; import { CanActivate,Router,ActivatedRouteSnapshot,RouterStateSnapshot } from '@angular/router'; import { AuthService } from './auth.service'; @Injectable() export class AuthGuard implements CanActivate { constructor(private AuthService: AuthService,private router: Router) {} canActivate(route: ActivatedRouteSnapshot,state: RouterStateSnapshot) { if (this.AuthService.loggedIn) { return true; } this.router.navigate(['login']); return false; } }
这是AuthService,它检查用户的登录,并将结果绑定到其构造函数中的“loggedIn”属性.
import { Injectable } from '@angular/core'; import { AngularFire } from 'angularfire2'; import { Router } from '@angular/router'; @Injectable() export class AuthService { loggedIn: boolean = false; constructor( public af: AngularFire,public router: Router) { af.auth.subscribe(user => { if(user){ this.loggedIn = true; } }); } }
这里的问题显然是不同步的. AuthGuard的canActivate()总是返回一个false值,因为订阅没有及时收到数据,将“loggedIn”更改为true.
解决这个问题的最佳做法是什么?
编辑:
更改了AuthGuard返回一个可观察值.
canActivate(route: ActivatedRouteSnapshot,state: RouterStateSnapshot) { return this.af.auth.map((auth) => { if (!auth) { this.router.navigateByUrl('login'); return false; } return true; }); }
它的作品,因为你没有被重定向到登录…但目标AuthGuarded组件没有渲染.
不知道是否与我的app.routes有关.这是该部分的代码:
const routes: Routes = [ { path: '',component: MainComponent,canActivate: [AuthGuard] },... ]; export const routing = RouterModule.forRoot(routes);
使用.take(1)完成可观察的操作,使组件呈现.
import {Observable} from "rxjs/Observable"; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/take'; canActivate(route: ActivatedRouteSnapshot,state: RouterStateSnapshot) { return this.af.auth.map((auth) => { if (!auth) { this.router.navigateByUrl('login'); return false; } return true; }).take(1); }