1

ほとんどのルートにアクセスする前に認証が必要な Play + AngularJS を使用して構築している単純なアプリがあります。ログイン フローには、セッション ID をブラウザーのローカル ストレージに保存し、ユーザーがアプリに戻るたびに、サーバー側の有効な承認済みデータベース セッション エントリにマップされる "remember me" 機能が含まれています。

私が抱えている問題は、モジュールのrun() 関数でセッション チェック (Cookie を抽出し、サーバーと比較する) を行うことです。

    .run(function ($rootScope, $http, $cookieStore, $location) {
        // <snip>

        // check if there is already a session?
        var sessionId = window.localStorage["session.id"];
        if (sessionId == null) {
            sessionId = $cookieStore.get("session.id");
        }

        if (sessionId != null) {
            $http.get("/sessions/" + sessionId)
                .success(function (data) {
                    $http.defaults.headers.common['X-Session-ID'] = data.id;
                    $cookieStore.put("session.id", data.id);

                    $rootScope.user = data.user;
                })
                .error(function () {
                    // remove the cookie, since it's dead
                    $cookieStore.remove("session.id");
                    window.localStorage.removeItem("session.id");
                    $location.path("/login");
                });
        } else {
            if ($location.path() != "/login" && $location.path() != "/signup") {
                $location.path("/login");
            }
        }
    });

問題は、この関数が AJAX 呼び出しを実行し、完了するまでセッションが有効かどうかわからないことです。ただし、($routeProvider によって選択されたルートを介して) ロードするコントローラーは、他の AJAX 呼び出しが終了する前に開始されることが多い別の AJAX 呼び出しを起動する可能性があり、その結果、競合状態になり、最初の要求で 401 応答コードが返されます。

だから私の質問は、アプリの他の部分が実行される前に、実行を強制的に (関連する $http 呼び出しで) 完了するにはどうすればよいですか? ここで $q/promise を使用してみましたが、違いはないようです (おそらく実行関数は約束を尊重しません)。私は$routeProviderresolveの機能を使用するようにアドバイスしてきましたが、何をすべきか正確にはわかりません。とにかく、すべてのルートにそれを入れなければならないことにあまり興奮していません.

これはかなり一般的なユースケースであり、毎日解決されていると思います。うまくいけば、誰かが私のコードで何らかの方向性を教えてくれたり、「remember me」と AngularJS のアプローチを共有したりできます。

4

1 に答える 1

0

サーバーからセッションを取得した後、アプリを手動でブートストラップする必要があります。たとえば、jQuery を使用すると簡単です。jQuery がなくても、ブートストラップの前にインジェクターを使用して $http にアクセスできます。

$.get(server,function(){ 
//success , set variable.
}).fail(function (){ 
//failed :( redirect to login or set session to false etc... null
})
.always(function(){
//alwyas bootstrap in both case and set result as a constant or variable Angular.module('app').variable('session',sessionResult);
});

私は今電話中ですが、これはあなたにアイデアを与えるはずです

于 2015-09-13T21:56:19.477 に答える