1. ホーム
  2. typescript

[解決済み] Angular2 canActivate() 非同期関数呼び出し

2023-01-26 01:46:47

質問

Angular2のルーターガードを使って、アプリ内のいくつかのページへのアクセスを制限しようとしています。 私はFirebase Authenticationを使用しています。 ユーザーがFirebaseでログインしているかどうかを確認するために、私は以下を呼び出す必要があります。 .subscribe() を呼び出す必要があります。 FirebaseAuth オブジェクトをコールバックで返します。 これはガードのためのコードです。

import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AngularFireAuth } from "angularfire2/angularfire2";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Rx";

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(private auth: AngularFireAuth, private router: Router) {}

    canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<boolean>|boolean {
        this.auth.subscribe((auth) => {
            if (auth) {
                console.log('authenticated');
                return true;
            }
            console.log('not authenticated');
            this.router.navigateByUrl('/login');
            return false;
        });
    }
}

ガードのあるページに移動したとき、どちらかの authenticated または not authenticated がコンソールに出力されます (firebaseからの応答を待つのに若干の時間がかかった後)。 しかし、ナビゲーションが完了することはありません。 また、ログインしていない場合、リダイレクトで /login ルートにリダイレクトされます。 つまり、私が抱えている問題は return true がユーザーに要求されたページを表示しないことです。 私はこれがコールバックを使用しているためであると仮定していますが、私はそれを行う方法を見つけることができません。 何か考えがありますか?

どのように解決するのですか?

canActivate を返す必要があります。 Observable を返す必要があります。

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(private auth: AngularFireAuth, private router: Router) {}

    canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<boolean>|boolean {
        return this.auth.map((auth) => {
            if (auth) {
                console.log('authenticated');
                return true;
            }
            console.log('not authenticated');
            this.router.navigateByUrl('/login');
            return false;
        }).first(); // this might not be necessary - ensure `first` is imported if you use it
    }
}

があり return が抜けているので map() の代わりに subscribe() というのは subscribe()Subscription ではなく Observable