2

ASP.NET Core MVC で Angular2 を使用しており、手動の URL ナビゲーションの管理は正常に機能し、サーバーは Angular2 でホーム ビューを正常に読み込んでいます。

ユーザー認証では、次のようなセッション変数を設定しています:

HttpHelper.HttpContext.Session.SetString("isLoggedIn", true.ToString() );

私が望むのは、ユーザーがアプリケーションに入った後、手動でナビゲートして特定のルートをロードしたい場合、サービスが ASP コントローラーを呼び出して、ユーザーが既に認証されているかどうかを確認して、ガードが許可するようにすることです。ルーティング。代わりに、ガードはデフォルトで false に設定されており、明らかにログイン ページにリダイレクトされます。

auth.service の IsLoggedIn 値を更新するために呼び出したい ASP コントローラー メソッドを次に示します。

[HttpGet]
public IActionResult IsConnectedState()
{
    if (!String.IsNullOrWhiteSpace(HttpHelper.HttpContext.Session.GetString("isLoggedIn")))
        return Ok(true);
    else
        return Ok(false);
}

私のAuthenticationGuardがAuthenticationServiceを呼び出して、認証された状態を管理するブール値を更新できるように:編集:より明確な説明のためにauth.guard.tsコード全体を貼り付けます

@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {
    if (!this.authService.isLoggedIn) {
        this.authService.setupLoggedInState().subscribe(() => {
            alert("guard check : " + this.authService.isLoggedIn);
            });
        }
    }

    canActivate()
    {
        if (this.authService.isLoggedIn) {
            return true;
        }

        this.router.navigate(['/login']);
        return false;
    }
}

次のコードで、私の auth.service のブール値を更新します。

setupLoggedInState() {
    alert("Setting Up");

    // Setting up the Http call 
    let lControllerAction: string = "/IsConnectedState";
    let lControllerFullURL: string = this.controllerURL + lControllerAction;
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });

    // Call my ASP Controller IsConnectedState() method
    return this.http.get(lControllerFullURL, options)
        .map((res: any) => {
            // Réponse reçue du WebService
            let data = res.json();
            alert(data);
            if (data == true) {
                this.isLoggedIn = true;
            }
        }
        ).catch(this.handleError);
}

問題は、保護されたルートを手動でロードしようとすると発生します。サービスのブール値が更新される前に、ログイン ページにリダイレクトされます。この問題を管理するためにどのようなソリューションをセットアップできるかわかりません...

電話してみた

if (!this.authService.isLoggedIn) {
    this.authService.setupLoggedInState().subscribe(() => { });
}
  • 私のガードコンストラクターで
  • 私のサービスコンストラクターで

しかし、それはまだ適切なタイミングで行われていません。私の最善の推測は、最初の AppModule をロードするときにこれを管理することですが、これが適切なタイミングであったとしても、Angular2 がブートストラップを終了するまでにブール値が更新されるという保証はありません。ブラウザをブロックするため、本当に悪い解決策です...どんなアイデアでも本当に役に立ちます。

PS : 今日も同様の投稿をしましたが、別の問題のためだったので、混乱を避けるためにここにリンクします:手動 URL ナビゲーションでのユーザー認証状態の管理

4

1 に答える 1

1

呼び出しsubscribe()によって自動的に値が提供されるわけではありません。これがサーバーへのリクエストを呼び出した場合、レスポンスが到着するまでに非常に時間がかかります。ブラウザは引き続きコードを実行し、最終的にサーバーからの応答が到着すると、渡されたコールバックがsubscribe(...)オブザーバブルによって呼び出されます。ルーターがオブザーバブルが応答を発行するのを待つことができるように、オブザーバブルを返すことにより、AuthGuard をオブザーバブルまたは実際にはルーターを待機させる必要がありますcanActivate()

@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {
  canActivate() {
    return this.authService.checkLoggedIn
    .map(loggedIn => {
      if(loggedIn) {
        return true;
      } else {
        this.router.navigate(['/login']); // not tried myself to navigate here
        return false;
      }
    });
  }
}


@Injectable()
class LoginService {
  constructor(private http:Http) {}

  checkLoggeIn() {
    return.http.get(someUrl).map(val => val.json());
  }
}

RxJs 5 で Angular 2 Http ネットワーク呼び出しの結果を共有する正しい方法は何ですか? を参照してください。HTTP リクエストからの結果をキャッシュする方法の詳細については、 を参照してください。

于 2016-08-26T13:22:48.227 に答える