6

私のアプリでは、ユーザーがログインしているとき、authService内部フラグを設定していますisAuthenticated$routeChangeStartこれで、ルートが変更されるたびに、チェックするイベントにリスナーがアタッチされますauthService.isAuthenticated()。いいえの場合は、ログイン ルートにリダイレクトする必要があります。

問題は、ユーザーがページを更新したとき (すべてのauthService設定が失われたとき)、再度ログインに戻ったときです (サーバー上で有効なセッションを保持している間)。これは私が望むものではありません。

私がしたいのは、ユーザーが認証された場合に情報を取得するまで、ルート変更を「ブロック」することです (更新後など、authService情報が利用できない場合はサーバーから)。authService私はそのような機能を持っていますauthService

        // returns promise
        currentUser: function() {
            if (authService.isAuthenticated()) {
                return $q.when(authService.loggedUser);
            }
            return $http.get('/session').then(function(response) {
                authService.loggedUser = response.user;
                return $q.when(authService.loggedUser);
            });
        }

イベントリスナーで使用したいと考えています。

    $rootScope.$on("$routeChangeStart", function (event, next, current) {
        if(isRouteRestricted(next)) {
            authService.currentUser().then(null, function() {
                $location.path('/login');
            });
        }
    });

問題は、期待どおりに機能しないことです。ターゲット ルートが非常に短時間だけ表示された後、ユーザーがリダイレクトされます。約束の性質によるものだと思いますが、この「まばたき」効果を取り除くにはどうすればよいですか?

4

2 に答える 2

4

ユーザーがルートにアクセスできないようにするには、いくつかのことを行う必要があります。

まず、ルートを設定し、'access' : allowAnonymous : true または false のようなプロパティを追加します。

// in app.js
var myApp = angular.module('myApp',['ngResource', 'ngCookies', 'ngRoute']);       
myApp.config(function ($httpProvider, $routeProvider) {
   window.routes = {
        '/Login':
           { templateUrl: '/Account/Login',
             controller: 'AccountController',
             access : {allowAnonymous : true}
           },
        '/MembersPage':
           { templateUrl: '/Home/SomePage,
             controller: SomePageController',
             access: {allowAnonymous:false}
           }
         };

        for (var path in window.routes) {
           $routeProvider.when(path, window.routes[path]);
    }
    $routeProvider.otherwise({ redirectTo: '/Login' });
});   

次に、認証されたユーザーを認識する必要があります。

それにはいくつかの方法がありますが、私は「サービス」の使用全体で AngularJS の機能を使用することを好みます。したがって、現在のユーザー名と、認証されているかどうかを示す値を格納する「UserService」を作成しました。

// in UserService.js
myApp.factory('userService', function () {
var user = {
    isLogged: false,
    username: '',       
};

var reset = function() {
    user.isLogged = false;
    user.username = '';
};

return {
    user: user,
    reset : reset
  };
});

最後に、ルート変更イベントをキャプチャし、それに応じて処理します。

サービスを配置したら、それを使用してルートのチェック機能を実装します。ルート変更イベントをインターセプトするメソッドはいくつかありますが、ユーザーがリダイレクトされる前に発生したメソッドのみに関心があるため、認証されているかどうかを確認できます: '$routeChangeStart'、'$locationChangeStart'。ここで、ユーザーがアクセスしようとしているルートで匿名アクセスが許可されているかどうか、およびユーザーがログインしているかどうかを確認できます。失敗した場合は、エラー メッセージを表示し、ユーザーをログイン ページにリダイレクトできます。

// in RootController.js
myApp.controller('RootController',
function ($scope, $route, $routeParams, $location, $rootScope, authenticationService,   
userService, toaster) {
 $scope.user = userService.user;
 $scope.$on('$routeChangeStart', function (e, next, current) {               
     if (next.access != undefined && !next.access.allowAnonymous && !$scope.user.isLogged) {
                $location.path("/Login");                   
            }
        });

        $scope.logout = function () {
            authenticationService.logout()
                .success(function (response) {
                    userService.reset();                       
                    toaster.pop("info", 'You are logged out.', '');
                });
        };

 $rootScope.$on("$locationChangeStart", function (event, next, current) {
  for (var i in window.routes) {
    if (next.indexOf(i) != -1) {
     if (!window.routes[i].access.allowAnonymous && !userService.user.isLogged) {
          toaster.pop("error", 'You are not logged in!', '');
             $location.path("/Login");                                                 
                    }
                }
            }
        });
    });

完全な記事はこちら: http://net-daylight.blogspot.ro/

それが役に立てば幸い!

于 2013-12-02T12:27:17.923 に答える