Reindirizzamento verso un determinato percorso in base alla condizione


493

Sto scrivendo una piccola app AngularJS che ha una vista di accesso e una vista principale, configurate in questo modo:

$routeProvider
 .when('/main' , {templateUrl: 'partials/main.html',  controller: MainController})
 .when('/login', {templateUrl: 'partials/login.html', controller: LoginController})
 .otherwise({redirectTo: '/login'});

Il mio LoginController controlla la combinazione utente / passaggio e imposta una proprietà su $ rootScope riflettendo questo:

function LoginController($scope, $location, $rootScope) {
 $scope.attemptLogin = function() {
   if ( $scope.username == $scope.password ) { // test
        $rootScope.loggedUser = $scope.username;
        $location.path( "/main" );
    } else {
        $scope.loginError = "Invalid user/pass.";
    }
}

Tutto funziona, ma se accedo http://localhost/#/main accedo finisco per bypassare la schermata di accesso. Volevo scrivere qualcosa del tipo "ogni volta che cambia il percorso, se $ rootScope.loggedUser è null, reindirizzare a / login"

...

... aspettare. Posso ascoltare i cambiamenti di percorso in qualche modo? Pubblicherò comunque questa domanda e continuerò a cercare.


3
Giusto per chiarire: mentre molte soluzioni di seguito funzionano bene, recentemente sono stato più propenso ad accettare la risposta di @ Oran di seguito - ovvero, fare in modo che il server risponda con un codice 401 quando viene richiesto un URL sensibile e utilizzare tali informazioni per controllare la "casella di accesso" sul client. (Comunque la giuria è ancora fuori sul bit "accodamento richieste rifiutate e ri-emetterle in seguito", almeno per me :))
st.never

Risposte:


510

Dopo un po 'di approfondimento su alcuni documenti e codice sorgente, penso di averlo fatto funzionare. Forse questo sarà utile per qualcun altro?

Ho aggiunto quanto segue alla mia configurazione del modulo:

angular.module(...)
 .config( ['$routeProvider', function($routeProvider) {...}] )
 .run( function($rootScope, $location) {

    // register listener to watch route changes
    $rootScope.$on( "$routeChangeStart", function(event, next, current) {
      if ( $rootScope.loggedUser == null ) {
        // no logged user, we should be going to #login
        if ( next.templateUrl != "partials/login.html" ) {
          // not going to #login, we should redirect now
          $location.path( "/login" );
        }
      }         
    });
 })

L'unica cosa che sembra strana è che ho dovuto testare il nome parziale ( login.html) perché l'oggetto "successivo" Route non aveva un URL o qualcos'altro. Forse c'è un modo migliore?


13
Fantastico, grazie per aver condiviso la tua soluzione. Una cosa da notare: nella versione attuale, è "next. $ Route.templateUrl"
doubledriscoll

5
Se guardi le richieste di rete in Chrome Inspector, la route che viene reindirizzata (perché l'utente non ha effettuato l'accesso) viene comunque chiamata e viene inviata una risposta al browser, quindi viene chiamato il percorso reindirizzato "/ login". Pertanto, questo metodo non è utile in quanto gli utenti non registrati possono vedere la risposta per una route a cui non dovrebbero avere accesso.
sonicboom,

34
Utilizzare $ locationChangeStart invece di $ routeChangeStart per impedire che la route venga chiamata e che consenta agli utenti non autenticati di visualizzare i contenuti a cui non dovrebbero avere accesso.
sonicboom,

17
Ricorda che questo è il client. Dovrebbe esserci anche una barriera sul lato server.
Neikos,

2
@sonicboom $ locationChangeStart non ha senso se non tutte le route richiedono l'autenticazione, con $ routeChangeStart puoi avere metadati sugli oggetti della route, ad esempio se è autenticato o quali ruoli sono richiesti per quella route. Il tuo server dovrebbe gestire la mancata visualizzazione di contenuti non autenticati e AngularJS non inizierà l'elaborazione fino a dopo la modifica del percorso, quindi non dovrebbe essere mostrato nulla.
Chris Nicola,

93

Ecco forse una soluzione più elegante e flessibile con proprietà di risoluzione "risoluzione" e "promesse" che consentono l'eventuale caricamento dei dati su regole di routing e routing in base ai dati.

Specificare una funzione in "risoluzione" nella configurazione del routing e nella funzione caricare e controllare i dati, eseguire tutti i reindirizzamenti. Se è necessario caricare i dati, si restituisce una promessa, se è necessario eseguire il reindirizzamento - rifiutare la promessa prima. Tutti i dettagli sono disponibili nelle pagine di documentazione di $ routerProvider e $ q .

'use strict';

var app = angular.module('app', [])
    .config(['$routeProvider', function($routeProvider) {
        $routeProvider
            .when('/', {
                templateUrl: "login.html",
                controller: LoginController
            })
            .when('/private', {
                templateUrl: "private.html",
                controller: PrivateController,
                resolve: {
                    factory: checkRouting
                }
            })
            .when('/private/anotherpage', {
                templateUrl:"another-private.html",
                controller: AnotherPriveController,
                resolve: {
                    factory: checkRouting
                }
            })
            .otherwise({ redirectTo: '/' });
    }]);

var checkRouting= function ($q, $rootScope, $location) {
    if ($rootScope.userProfile) {
        return true;
    } else {
        var deferred = $q.defer();
        $http.post("/loadUserProfile", { userToken: "blah" })
            .success(function (response) {
                $rootScope.userProfile = response.userProfile;
                deferred.resolve(true);
            })
            .error(function () {
                deferred.reject();
                $location.path("/");
             });
        return deferred.promise;
    }
};

Per la gente di lingua russa c'è un post su habr " Вариант условного раутинга в AngularJS ."


1
perché la funzione checkRouting è mappata in fabbrica? Importa a cosa è mappato?
honkskillet,

@honkskillet: dai documenti angolari $ routeProvider: "factory - {string | function}: se stringa, allora è un alias per un servizio. Altrimenti se funzione, allora viene iniettata e il valore restituito viene trattato come dipendenza. Se il il risultato è una promessa, viene risolto prima che il suo valore venga iniettato nel controller. Tenere presente che ngRoute. $ routeParams farà ancora riferimento alla route precedente all'interno di queste funzioni di risoluzione. Utilizzare $ route.current.params per accedere ai nuovi parametri della route, anziché." Anche dai documenti sulla risoluzione: "Se una delle promesse viene rifiutata, viene generato l'evento $ routeChangeError."
Tim Perry,

Se ui.routerviene utilizzato, utilizzare $stateProvider invece di $routeProvider.
TRiNE,

61

Ho provato a fare lo stesso. È venuto con un'altra soluzione più semplice dopo aver lavorato con un collega. Ho impostato un orologio $location.path(). Questo è il trucco. Sto appena iniziando a imparare AngularJS e trovo che questo sia più pulito e leggibile.

$scope.$watch(function() { return $location.path(); }, function(newValue, oldValue){  
    if ($scope.loggedIn == false && newValue != '/login'){  
            $location.path('/login');  
    }  
});

Questo sembra molto interessante. Sei riuscito a pubblicare un esempio da qualche parte?
kyleroche,

3
Dove si imposta l'orologio?
FreakTheMighty,

3
@freakTheMighty Devi impostare l'orologio nella tua funzione mainCtrl, dove ng-controller è impostato su mainCtrl. ad es. <body ng-controller = "mainCtrl">
user1807337

5
Penso che sia giusto che se viene dato un voto negativo, dovrebbe avere un commento con ragione. Aiuterà come strumento di apprendimento.
user1807337

37

Un modo diverso di implementare il reindirizzamento degli accessi consiste nell'utilizzare eventi e intercettori come descritto qui . L'articolo descrive alcuni vantaggi aggiuntivi come il rilevamento di un accesso richiesto, l'accodamento delle richieste e la loro riproduzione una volta effettuato l'accesso.

Puoi provare una demo funzionante qui e visualizzare la fonte demo qui .


3
Potresti aggiornare questa risposta per includere le informazioni pertinenti dai collegamenti? In questo modo continuerà a essere utile per i visitatori anche se i link non funzionano.
josliber

34

1. Imposta l'utente corrente globale.

Nel servizio di autenticazione, imposta l'utente attualmente autenticato sull'ambito radice.

// AuthService.js

  // auth successful
  $rootScope.user = user

2. Impostare la funzione di autenticazione su ciascun percorso protetto.

// AdminController.js

.config(function ($routeProvider) {
  $routeProvider.when('/admin', {
    controller: 'AdminController',
    auth: function (user) {
      return user && user.isAdmin
    }
  })
})

3. Controlla l'autenticità ad ogni cambio di rotta.

// index.js

.run(function ($rootScope, $location) {
  $rootScope.$on('$routeChangeStart', function (ev, next, curr) {
    if (next.$$route) {
      var user = $rootScope.user
      var auth = next.$$route.auth
      if (auth && !auth(user)) { $location.path('/') }
    }
  })
})

In alternativa, è possibile impostare le autorizzazioni sull'oggetto utente e assegnare a ciascuna route un'autorizzazione, quindi controllare l'autorizzazione nel callback dell'evento.


@malcolmhall yup, questo è opt-in e tu vuoi rinunciare. Aggiungi invece un booleano "pubblico" a percorsi pubblici come la pagina di accesso e reindirizzaif (!user && !next.$$route.public)
AJcodez

Qualcuno potrebbe spiegarmi next.$$routeper favore ? Non trovo nulla nei documenti angolari che descrivono gli argomenti forniti a un $routeChangeStartevento, ma presumo nexte currsono una sorta di oggetti di localizzazione? Il $$routebit è difficile da google.
skagedal,

2
Vedo ora che la $$routeproprietà è una variabile privata di Angular. Non dovresti fare affidamento su questo, vedi ad esempio: stackoverflow.com/a/19338518/1132101 - se lo fai, il tuo codice potrebbe rompersi quando Angular cambia.
skagedal,

2
Ho trovato un modo per accedere al percorso senza accesso a una proprietà privata o di dover scorrere $route.routesper costruire una lista (come in @ di thataustin risposta): ottenere il percorso per la posizione con next.originalPathe l'uso che per indicizzare $route.routes: var auth = $route.routes[next.originalPath].
skagedal,

Per quanto riguarda la risposta alla mia domanda di tre commenti fa sugli argomenti presentati all'evento - sembrano davvero non documentati, vedi questo problema che fa riferimento anche a questa domanda SO: github.com/angular/angular.js/issues/ 10994
skagedal,

27

Ecco come l'ho fatto, nel caso aiuti qualcuno:

Nella configurazione, ho impostato un publicAccessattributo sui pochi percorsi che voglio aprire al pubblico (come login o registrati):

$routeProvider
    .when('/', {
        templateUrl: 'views/home.html',
        controller: 'HomeCtrl'
    })
    .when('/login', {
        templateUrl: 'views/login.html',
        controller: 'LoginCtrl',
        publicAccess: true
    })

quindi in un blocco di esecuzione, ho impostato un listener $routeChangeStartsull'evento a cui reindirizza a '/login'meno che l'utente non abbia accesso o il percorso sia accessibile pubblicamente:

angular.module('myModule').run(function($rootScope, $location, user, $route) {

    var routesOpenToPublic = [];
    angular.forEach($route.routes, function(route, path) {
        // push route onto routesOpenToPublic if it has a truthy publicAccess value
        route.publicAccess && (routesOpenToPublic.push(path));
    });

    $rootScope.$on('$routeChangeStart', function(event, nextLoc, currentLoc) {
        var closedToPublic = (-1 === routesOpenToPublic.indexOf($location.path()));
        if(closedToPublic && !user.isLoggedIn()) {
            $location.path('/login');
        }
    });
})

Potresti ovviamente cambiare la condizione da isLoggedIna qualsiasi altra cosa ... solo mostrando un altro modo per farlo.


e qual è l'utente negli argomenti del blocco di esecuzione? un servizio?
Mohamnag,

si, è un servizio che si occupa di controllare i cookie, ecc. per vedere se l'utente ha effettuato l'accesso.
thataustin

Puoi accedere al percorso come nextLoc.$$route.publicAccessbtw.
AJcodez,

O usa $route.routes[nextLoc.originalPath], che non usa una variabile privata.
skagedal,

1
In realtà, puoi semplicemente controllare nextLoc && nextLoc.publicAccess!
skagedal,

9

Lo sto facendo usando intercettori. Ho creato un file di libreria che può essere aggiunto al file index.html. In questo modo avrai una gestione globale degli errori per le chiamate di servizio di riposo e non dovrai preoccuparti di tutti gli errori singolarmente. Più in basso ho anche incollato la mia libreria di login di base-auth. Lì puoi vedere che controllo anche l'errore 401 e reindirizzo a una posizione diversa. Vedi lib / ea-basic-auth-login.js

lib / http-error-handling.js

/**
* @ngdoc overview
* @name http-error-handling
* @description
*
* Module that provides http error handling for apps.
*
* Usage:
* Hook the file in to your index.html: <script src="lib/http-error-handling.js"></script>
* Add <div class="messagesList" app-messages></div> to the index.html at the position you want to
* display the error messages.
*/
(function() {
'use strict';
angular.module('http-error-handling', [])
    .config(function($provide, $httpProvider, $compileProvider) {
        var elementsList = $();

        var showMessage = function(content, cl, time) {
            $('<div/>')
                .addClass(cl)
                .hide()
                .fadeIn('fast')
                .delay(time)
                .fadeOut('fast', function() { $(this).remove(); })
                .appendTo(elementsList)
                .text(content);
        };

        $httpProvider.responseInterceptors.push(function($timeout, $q) {
            return function(promise) {
                return promise.then(function(successResponse) {
                    if (successResponse.config.method.toUpperCase() != 'GET')
                        showMessage('Success', 'http-success-message', 5000);
                    return successResponse;

                }, function(errorResponse) {
                    switch (errorResponse.status) {
                        case 400:
                            showMessage(errorResponse.data.message, 'http-error-message', 6000);
                                }
                            }
                            break;
                        case 401:
                            showMessage('Wrong email or password', 'http-error-message', 6000);
                            break;
                        case 403:
                            showMessage('You don\'t have the right to do this', 'http-error-message', 6000);
                            break;
                        case 500:
                            showMessage('Server internal error: ' + errorResponse.data.message, 'http-error-message', 6000);
                            break;
                        default:
                            showMessage('Error ' + errorResponse.status + ': ' + errorResponse.data.message, 'http-error-message', 6000);
                    }
                    return $q.reject(errorResponse);
                });
            };
        });

        $compileProvider.directive('httpErrorMessages', function() {
            return {
                link: function(scope, element, attrs) {
                    elementsList.push($(element));
                }
            };
        });
    });
})();

css / http-error-handling.css

.http-error-message {
    background-color: #fbbcb1;
    border: 1px #e92d0c solid;
    font-size: 12px;
    font-family: arial;
    padding: 10px;
    width: 702px;
    margin-bottom: 1px;
}

.http-error-validation-message {
    background-color: #fbbcb1;
    border: 1px #e92d0c solid;
    font-size: 12px;
    font-family: arial;
    padding: 10px;
    width: 702px;
    margin-bottom: 1px;
}

http-success-message {
    background-color: #adfa9e;
    border: 1px #25ae09 solid;
    font-size: 12px;
    font-family: arial;
    padding: 10px;
    width: 702px;
    margin-bottom: 1px;
}

index.html

<!doctype html>
<html lang="en" ng-app="cc">
    <head>
        <meta charset="utf-8">
        <title>yourapp</title>
        <link rel="stylesheet" href="css/http-error-handling.css"/>
    </head>
    <body>

<!-- Display top tab menu -->
<ul class="menu">
  <li><a href="#/user">Users</a></li>
  <li><a href="#/vendor">Vendors</a></li>
  <li><logout-link/></li>
</ul>

<!-- Display errors -->
<div class="http-error-messages" http-error-messages></div>

<!-- Display partial pages -->
<div ng-view></div>

<!-- Include all the js files. In production use min.js should be used -->
<script src="lib/angular114/angular.js"></script>
<script src="lib/angular114/angular-resource.js"></script>
<script src="lib/http-error-handling.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>

lib / EA-base-auth-login.js

Quasi lo stesso può essere fatto per il login. Qui hai la risposta al reindirizzamento ($ location.path ("/ login")).

/**
* @ngdoc overview
* @name ea-basic-auth-login
* @description
*
* Module that provides http basic authentication for apps.
*
* Usage:
* Hook the file in to your index.html: <script src="lib/ea-basic-auth-login.js">  </script>
* Place <ea-login-form/> tag in to your html login page
* Place <ea-logout-link/> tag in to your html page where the user has to click to logout
*/
(function() {
'use strict';
angular.module('ea-basic-auth-login', ['ea-base64-login'])
    .config(['$httpProvider', function ($httpProvider) {
        var ea_basic_auth_login_interceptor = ['$location', '$q', function($location, $q) {
            function success(response) {
                return response;
            }

            function error(response) {
                if(response.status === 401) {
                    $location.path('/login');
                    return $q.reject(response);
                }
                else {
                    return $q.reject(response);
                }
            }

            return function(promise) {
                return promise.then(success, error);
            }
        }];
        $httpProvider.responseInterceptors.push(ea_basic_auth_login_interceptor);
    }])
    .controller('EALoginCtrl', ['$scope','$http','$location','EABase64Login', function($scope, $http, $location, EABase64Login) {
        $scope.login = function() {
            $http.defaults.headers.common['Authorization'] = 'Basic ' + EABase64Login.encode($scope.email + ':' + $scope.password);
            $location.path("/user");
        };

        $scope.logout = function() {
            $http.defaults.headers.common['Authorization'] = undefined;
            $location.path("/login");
        };
    }])
    .directive('eaLoginForm', [function() {
        return {
            restrict:   'E',
            template:   '<div id="ea_login_container" ng-controller="EALoginCtrl">' +
                        '<form id="ea_login_form" name="ea_login_form" novalidate>' +
                        '<input id="ea_login_email_field" class="ea_login_field" type="text" name="email" ng-model="email" placeholder="E-Mail"/>' +
                        '<br/>' +
                        '<input id="ea_login_password_field" class="ea_login_field" type="password" name="password" ng-model="password" placeholder="Password"/>' +
                        '<br/>' +
                        '<button class="ea_login_button" ng-click="login()">Login</button>' +
                        '</form>' +
                        '</div>',
            replace: true
        };
    }])
    .directive('eaLogoutLink', [function() {
        return {
            restrict: 'E',
            template: '<a id="ea-logout-link" ng-controller="EALoginCtrl" ng-click="logout()">Logout</a>',
            replace: true
        }
    }]);

angular.module('ea-base64-login', []).
    factory('EABase64Login', function() {
        var keyStr = 'ABCDEFGHIJKLMNOP' +
            'QRSTUVWXYZabcdef' +
            'ghijklmnopqrstuv' +
            'wxyz0123456789+/' +
            '=';

        return {
            encode: function (input) {
                var output = "";
                var chr1, chr2, chr3 = "";
                var enc1, enc2, enc3, enc4 = "";
                var i = 0;

                do {
                    chr1 = input.charCodeAt(i++);
                    chr2 = input.charCodeAt(i++);
                    chr3 = input.charCodeAt(i++);

                    enc1 = chr1 >> 2;
                    enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                    enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                    enc4 = chr3 & 63;

                    if (isNaN(chr2)) {
                        enc3 = enc4 = 64;
                    } else if (isNaN(chr3)) {
                        enc4 = 64;
                    }

                    output = output +
                        keyStr.charAt(enc1) +
                        keyStr.charAt(enc2) +
                        keyStr.charAt(enc3) +
                        keyStr.charAt(enc4);
                    chr1 = chr2 = chr3 = "";
                    enc1 = enc2 = enc3 = enc4 = "";
                } while (i < input.length);

                return output;
            },

            decode: function (input) {
                var output = "";
                var chr1, chr2, chr3 = "";
                var enc1, enc2, enc3, enc4 = "";
                var i = 0;

                // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
                var base64test = /[^A-Za-z0-9\+\/\=]/g;
                if (base64test.exec(input)) {
                    alert("There were invalid base64 characters in the input text.\n" +
                        "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
                        "Expect errors in decoding.");
                }
                input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

                do {
                    enc1 = keyStr.indexOf(input.charAt(i++));
                    enc2 = keyStr.indexOf(input.charAt(i++));
                    enc3 = keyStr.indexOf(input.charAt(i++));
                    enc4 = keyStr.indexOf(input.charAt(i++));

                    chr1 = (enc1 << 2) | (enc2 >> 4);
                    chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                    chr3 = ((enc3 & 3) << 6) | enc4;

                    output = output + String.fromCharCode(chr1);

                    if (enc3 != 64) {
                        output = output + String.fromCharCode(chr2);
                    }
                    if (enc4 != 64) {
                        output = output + String.fromCharCode(chr3);
                    }

                    chr1 = chr2 = chr3 = "";
                    enc1 = enc2 = enc3 = enc4 = "";

                } while (i < input.length);

                return output;
            }
        };
    });
})();

2
Dovresti davvero stare lontano dal fare manipolazioni dom nel JS a meno che tu non sia in una direttiva. Se hai appena impostato la tua logica e poi usi ng-class per applicare una classe e attivare un'animazione CSS, ti ringrazierai in seguito.
Askdesigners,

7

Nel tuo file app.js:

.run(["$rootScope", "$state", function($rootScope, $state) {

      $rootScope.$on('$locationChangeStart', function(event, next, current) {
        if (!$rootScope.loggedUser == null) {
          $state.go('home');
        }    
      });
}])

4

È possibile reindirizzare a un'altra vista con angular-ui-router . A tale scopo, abbiamo il metodo $state.go("target_view"). Per esempio:

 ---- app.js -----

 var app = angular.module('myApp', ['ui.router']);

 app.config(function ($stateProvider, $urlRouterProvider) {

    // Otherwise
    $urlRouterProvider.otherwise("/");

    $stateProvider
            // Index will decide if redirects to Login or Dashboard view
            .state("index", {
                 url: ""
                 controller: 'index_controller'
              })
            .state('dashboard', {
                url: "/dashboard",
                controller: 'dashboard_controller',
                templateUrl: "views/dashboard.html"
              })
            .state('login', {
                url: "/login",
                controller: 'login_controller',
                templateUrl: "views/login.html"
              });
 });

 // Associate the $state variable with $rootScope in order to use it with any controller
 app.run(function ($rootScope, $state, $stateParams) {
        $rootScope.$state = $state;
        $rootScope.$stateParams = $stateParams;
    });

 app.controller('index_controller', function ($scope, $log) {

    /* Check if the user is logged prior to use the next code */

    if (!isLoggedUser) {
        $log.log("user not logged, redirecting to Login view");
        // Redirect to Login view 
        $scope.$state.go("login");
    } else {
        // Redirect to dashboard view 
        $scope.$state.go("dashboard");
    }

 });

----- HTML -----

<!DOCTYPE html>
<html>
    <head>
        <title>My WebSite</title>

        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="description" content="MyContent">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <script src="js/libs/angular.min.js" type="text/javascript"></script>
        <script src="js/libs/angular-ui-router.min.js" type="text/javascript"></script>
        <script src="js/app.js" type="text/javascript"></script>

    </head>
    <body ng-app="myApp">
        <div ui-view></div>
    </body>
</html>

3

Se non si desidera utilizzare angular-ui-router, ma si desidera caricare i controller in modo pigro tramite RequireJS, ci sono un paio di problemi con l'evento $routeChangeStartquando si utilizzano i controller come moduli RequireJS (caricamento in modalità lazy).

Non puoi essere sicuro che il controller verrà caricato prima che $routeChangeStartvenga attivato - in realtà non verrà caricato. Ciò significa che non è possibile accedere alle proprietà del nextpercorso come localso $$routeperché non sono ancora configurate.
Esempio:

app.config(["$routeProvider", function($routeProvider) {
    $routeProvider.when("/foo", {
        controller: "Foo",
        resolve: {
            controller: ["$q", function($q) {
                var deferred = $q.defer();
                require(["path/to/controller/Foo"], function(Foo) {
                    // now controller is loaded
                    deferred.resolve();
                });
                return deferred.promise;
            }]
        }
    });
}]);

app.run(["$rootScope", function($rootScope) {
    $rootScope.$on("$routeChangeStart", function(event, next, current) {
        console.log(next.$$route, next.locals); // undefined, undefined
    });
}]);

Ciò significa che non è possibile verificare i diritti di accesso lì.

Soluzione:

Poiché il caricamento del controller viene eseguito tramite risoluzione, puoi fare lo stesso con il controllo del controllo di accesso:

app.config(["$routeProvider", function($routeProvider) {
    $routeProvider.when("/foo", {
        controller: "Foo",
        resolve: {
            controller: ["$q", function($q) {
                var deferred = $q.defer();
                require(["path/to/controller/Foo"], function(Foo) {
                    // now controller is loaded
                    deferred.resolve();
                });
                return deferred.promise;
            }],
            access: ["$q", function($q) {
                var deferred = $q.defer();
                if (/* some logic to determine access is granted */) {
                    deferred.resolve();
                } else {
                    deferred.reject("You have no access rights to go there");
                }
                return deferred.promise;
            }],
        }
    });
}]);

app.run(["$rootScope", function($rootScope) {
    $rootScope.$on("$routeChangeError", function(event, next, current, error) {
        console.log("Error: " + error); // "Error: You have no access rights to go there"
    });
}]);

Nota qui che invece di usare l'evento $routeChangeStartche sto usando$routeChangeError


-4
    $routeProvider
 .when('/main' , {templateUrl: 'partials/main.html',  controller: MainController})
 .when('/login', {templateUrl: 'partials/login.html', controller: LoginController}).
 .when('/login', {templateUrl: 'partials/index.html', controller: IndexController})
 .otherwise({redirectTo: '/index'});

Questa è una configurazione di route di base ... Dove stiamo controllando le condizioni prima di reindirizzare alle route configurate ...?
TJ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.