我正在尝试使用Firebase Auth为Angular 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);
2 回答
使用.take(1)完成observable以使组件渲染 .
对于较新版本的
AngularFire
,您必须使用authState
代替:不要忘记从
rxjs/add/operator
导入take
,map
和do
.