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;
}
}
これは、ユーザーがログインしているかどうかを確認し、その結果をコンストラクターのプロパティ 'loggedIn' にバインドする AuthService です。
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() は、「loggedIn」を true に変更するのに間に合うようにサブスクリプションがデータを受信しないため、常に false の値を返します。
これを修正するためのベストプラクティスは何ですか?
編集:
Observable を返すように 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);