Скажем, у меня есть 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
не очень ясны, и есть несколько полезных примеров).
РЕДАКТИРОВАТЬ:
Судя по приведенным ниже ответам, для этого существует три основных подхода:
- Использование
resolve
для проверки входа в систему и невыполнения обещания, а затем перехват события$routeChangeError
для перенаправления http://www.sitepoint.com/implementing-authentication-angular-applications/ - Использование только события
$routeChangeStart
для проверки входа в систему и перенаправления http: // arthur .gonigberg.com / 29.06.2013 / angularjs-role-based-auth / - Использование просто разрешения для проверки входа в систему и перенаправления http://midgetontoes.com/blog/2014 / 08/31 / angularjs-check-user-login
Второй вариант - это то, что предложили два респондента.
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;
};
Просто, работает как шарм. Если мне когда-нибудь понадобится директива, я перетащу ее в сервис.
Это сообщение в блоге посвящено аутентификации пользователей. в 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');
}
});
}]);
$routeChangeStart
для захвата и предотвращения продолжения? Мне все равно нужно знать пути, и я бы предпочел сделать это в $routeProvider.when()
, если смогу, но это сработает. Это похоже на ответ @JasonvanderZeeuw ниже. Я прочитаю сообщение в блоге, спасибо
У меня была такая же проблема, и я сделал это так:
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...)
});
}
Надеюсь, это поможет!
$routeProvider
ничего, что могло бы помочь?
Похожие вопросы
Новые вопросы
angularjs
Используйте для вопросов об AngularJS (1.x), JavaScript-фреймворке с открытым исходным кодом. НЕ используйте этот тег для Angular 2 или более поздних версий; вместо этого используйте тег [angular].
$routeProvider
. Но это может быть где угодно, так как вы всегда можетеrequire()
или включить его иным образом.