web-dev-qa-db-fra.com

Angularjs ui-router. Comment rediriger vers la page de connexion

J'ai 4 états: tableau de bord , dahboard.main , dashboard.minor , connexion . Le tableau de bord est abstrait et il s'agit d'un état parent pour .minor et. états principaux . Ci-dessous est mon code:

.state('dashboard', {
        url: "/dashboard",
        abstract: true,
        templateUrl: "views/dashboard.html",
        resolve: {
            auth: function ($q, authenticationSvc) {
                var userInfo = authenticationSvc.getUserInfo();
                if (userInfo) {
                    return $q.when(userInfo);
                } else {
                    return $q.reject({ authenticated: false });
                }
            }
        },
        controller: "DashboardCtrl",
        data: { pageTitle: 'Example view' }
    })
    .state('dashboard.main', {
        url: "",
        templateUrl: "views/main.html",
        controller: "DashboardCtrl",
        data: { pageTitle: 'Main view' }
    })

Comme vous le voyez dans l'état du tableau de bord, j'ai l'option de résolution. Par ceci, je voudrais rediriger l'utilisateur vers la page de connexion s'il n'est pas autorisé. Pour cette raison, j'utilise le service spécial authenticationSvc :

.factory("authenticationSvc", ["$http", "$q", "$window", function ($http, $q, $window) {
    var userInfo;

    function login(email, password) {
        var deferred = $q.defer();

        $http.post("/api/login", { email: email, password: password })
            .then(function (result) {
                if(result.data.error == 0) {
                    userInfo = {
                        accessToken: result.data.accessToken
                    };
                    $window.sessionStorage["userInfo"] = JSON.stringify(userInfo);
                    deferred.resolve(userInfo);
                }
                else {
                    deferred.reject(error);
                }
            }, function (error) {
                deferred.reject(error);
            });

        return deferred.promise;
    }
    function getUserInfo() {
        return userInfo;
    }
    return {
        login: login,
        logout: logout,
        getUserInfo: getUserInfo
    };
}]);

Je vérifie la valeur d'authentification dans config :

.run(function($rootScope, $location, $state) {
    $rootScope.$state = $state;
    $rootScope.$on("routeChangeSuccess", function(userInfo) {
        consol.log(userInfo);
    });
    $rootScope.$on("routeChangeError", function(event, current, previous, eventObj) {
        if(eventObj.authenticated === false) {
            $state.go('login');
        }
    });
});

Mais malheureusement, lorsque je vais à la racine de mon site Web ou à l’état du tableau de bord, la page est vide. Quel est le problème avec ce code? Merci!

55
Yelnar

Le point est, ne pas rediriger si non nécessaire === si déjà redirigé vers l'état prévu. Il y a un plunker de travail avec une solution similaire

.run(function($rootScope, $location, $state, authenticationSvc) {


    $rootScope.$on( '$stateChangeStart', function(e, toState  , toParams
                                                   , fromState, fromParams) {

        var isLogin = toState.name === "login";
        if(isLogin){
           return; // no need to redirect 
        }

        // now, redirect only not authenticated

        var userInfo = authenticationSvc.getUserInfo();

        if(userInfo.authenticated === false) {
            e.preventDefault(); // stop current execution
            $state.go('login'); // go to login
        }
    });
});

Vérifiez-les pour une explication similaire:

77
Radim Köhler

Puisque vous utilisez le module UI-Router, vous devriez utiliser les événements $stateChangeStart, $stateChangeSuccess.

Vérifiez ce lien pour plus: https://github.com/angular-ui/ui-router/issues/17

Il y a aussi une faute de frappe dans consol.log(userInfo) dans console.

Vérifiez la console dans votre chrome-dev-tools. Cela donnera une idée s'il manque quelque chose d'autre.

4
Vamshi Suram

Attention, l'événement $stateChangeSuccess est en fait deprecated et n'est plus disponible dans le package angular-ui-route. Maintenant, ce comportement est géré par transition hooks . Vous pouvez atteindre votre objectif en utilisant $transitions.onStart comme suit:

run.$inject = ['$transitions', 'authenticationSvc'];
function run($transitions, authenticationSvc) {

  $transitions.onStart({}, function (trans) {
    var userInfo = authenticationSvc.getUserInfo();

    var $state = trans.router.stateService;

    if(userInfo.authenticated === false) {
        $state.go('login'); // go to login
    }
  });
}
0
guijob