Скажем, у меня есть 4 маршрута - 2 требуют, чтобы пользователь был авторизован, 2 - нет. Моя инициализация приложения выглядит так:

        $routeProvider.when('/open1',{templateUrl:'/open1.html',controller:'Open1'});
        $routeProvider.when('/open2',{templateUrl:'/open2.html',controller:'Open2'});
        $routeProvider.when('/secure1',{templateUrl:'/secure1.html',controller:'Secure1'});
        $routeProvider.when('/secure2',{templateUrl:'/secure2.html',controller:'Secure2'});

Маршруты /open1 и /open2 открыты для всех, в то время как маршруты /secure1 и /secure2 требуют, чтобы пользователь вошел в систему и, если нет, предпринять некоторые действия, например перенаправить на вход или запустить предупреждение. Я могу определить состояние пользователя, используя мою службу Auth и позвонив, например, Auth.isLogin(). Итак, результат будет:

  • переход к /open1 и /open2 всегда переходить к шаблону и контроллеру, объявленным выше
  • если Auth.isLogin() возвращает истину, /secure1 и /secure2 переходят к вышеуказанному шаблону и контроллеру
  • если Auth.isLogin() возвращает false, /secure1 и /secure2 предпринимают другие действия, например $location.path('/login')

Я мог бы добавить логику в контроллеры Secure1 и Secure2, которая проверяет, но она повторяется и смешивает обязанности, затрудняет их тестирование и т. Д.

Есть ли способ, которым я могу использовать $routeProvider, чтобы объявить «проверьте этот маршрут и этот маршрут, а если нет, перенаправить»? Я думал как-то использовать resolve, но не совсем уверен, как с ним работать (документы по resolve не очень ясны, и есть несколько полезных примеров).

РЕДАКТИРОВАТЬ:

Судя по приведенным ниже ответам, для этого существует три основных подхода:

Второй вариант - это то, что предложили два респондента.

10
deitch 18 Ноя 2014 в 15:03

3 ответа

Лучший ответ

Как и в моих комментариях выше, существует 3 разных пути (плюс возможность использовать директиву, если вы хотите управлять ею из HTML-шаблонов). В итоге я подписался на

https://midgetontoes.com/angularjs-check-user-login/

Который по сути выглядит следующим образом:

$routeProvider.when('/secure', {
    templateUrl: '/secure.html', 
    controller: 'Secure',
    resolve:{
        loggedIn:onlyLoggedIn
    }
 });

А затем onlyLoggedIn:

var onlyLoggedIn = function ($location,$q,Auth) {
    var deferred = $q.defer();
    if (Auth.isLogin()) {
        deferred.resolve();
    } else {
        deferred.reject();
        $location.url('/login');
    }
    return deferred.promise;
};

Просто, работает как шарм. Если мне когда-нибудь понадобится директива, я перетащу ее в сервис.

13
Garf365 14 Мар 2017 в 11:17

Это сообщение в блоге посвящено аутентификации пользователей. в AngularJS с помощью директив.

Сервис $ route выдает $ routeChangeStart перед изменением маршрута.

Если вы не используете директивы, вы можете поймать это событие, вызвав app.run (вы можете поместить его после кода, в котором вы определяете маршруты [app.config]). Например:

Для полного раскрытия информации я использую ui.router, а это адаптированный код из $ stateChangeStart Я использую в своем приложении

var app = angular.module('app');

app.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/open1',{templateUrl:'/open1.html',controller:'Open1'});
    $routeProvider.when('/open2',{templateUrl:'/open2.html',controller:'Open2'});
    $routeProvider.when('/secure1',{templateUrl:'/secure1.html',controller:'Secure1'});
    $routeProvider.when('/secure2',{templateUrl:'/secure2.html',controller:'Secure2'});
}]);

app.run(['$rootScope', '$location', 'Auth', function($rootScope, $location, Auth) {
    $rootScope.$on('$routeChangeStart', function(event, currRoute, prevRoute){
        var logged = Auth.isLogin();

        //check if the user is going to the login page
        // i use ui.route so not exactly sure about this one but you get the picture
        var appTo = currRoute.path.indexOf('/secure') !== -1;

        if(appTo && !logged) {
            event.preventDefault();
            $location.path('/login');
        }
    });
}]);
4
MKroeders 23 Июн 2016 в 18:19

У меня была такая же проблема, и я сделал это так:

var app = angular.module('myModule',["ui-bootstrap"]);

А затем прослушайте изменение местоположения в приложении (это также сработает при входе на страницу)

app.run(function ($rootScope, $location, $cookieStore) {
 $rootScope.$on("$locationChangeStart", function (event, next, current) {
    //Here you can check whatever you want (servercall, cookie...)
 });
}

Надеюсь, это поможет!

3
Jason van der Zeeuw 18 Ноя 2014 в 12:52