我试图使用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);
- }