Я пишу небольшое приложение AngularJS, которое имеет вид входа в систему и основной вид, настроенный так:
$routeProvider
.when('/main' , {templateUrl: 'partials/main.html', controller: MainController})
.when('/login', {templateUrl: 'partials/login.html', controller: LoginController})
.otherwise({redirectTo: '/login'});
Мой LoginController проверяет комбинацию пользователь / пароль и устанавливает свойство в $ rootScope, отражая это:
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.";
}
}
Все работает, но если я получаю доступ, в http://localhost/#/main
итоге я обхожу экран входа в систему. Я хотел написать что-то вроде "всякий раз, когда меняется маршрут, если $ rootScope.loggedUser равен нулю, то перенаправить в / login"
...
... подожди. Можно ли как-нибудь прослушать изменения маршрута? Я все равно отправлю этот вопрос и продолжу искать.
Ответы:
После некоторого погружения в документацию и исходный код, я думаю, что все заработало. Возможно, это будет полезно для кого-то еще?
Я добавил следующее в конфигурацию моего модуля:
Одна вещь, которая кажется странной, это то, что мне пришлось протестировать частичное имя (
login.html
), потому что у «следующего» объекта Route не было URL или чего-то еще. Может быть, есть лучший способ?источник
Вот, может быть, более элегантное и гибкое решение со свойством конфигурации «решить» и «обещаниями», обеспечивающими возможную загрузку данных о маршрутизации и правилах маршрутизации в зависимости от данных.
Вы указываете функцию в 'решить' в конфигурации маршрутизации и в функции загрузки и проверки данных, сделать все перенаправления. Если вам нужно загрузить данные, вы возвращаете обещание, если вам нужно сделать перенаправление - отклоните обещание до этого. Все подробности можно найти на страницах документации $ routerProvider и $ q .
Для русскоязычных людей есть пост на хабре " Вариант условного раутинга в AngularJS ."
источник
ui.router
используется, используйте$stateProvider
вместо$routeProvider
.Я пытался сделать то же самое. Придумал другое простое решение после работы с коллегой. У меня установлены часы
$location.path()
. Это делает трюк. Я только начинаю изучать AngularJS и нахожу это более понятным и читаемым.источник
Другим способом реализации перенаправления входа в систему является использование событий и перехватчиков, как описано здесь . В статье описываются некоторые дополнительные преимущества, такие как определение необходимости входа в систему, постановка запросов в очередь и их повторное воспроизведение после успешной регистрации.
Вы можете попробовать рабочую демо здесь и посмотреть демо источник здесь .
источник
1. Установите глобального текущего пользователя.
В вашей службе аутентификации установите текущего аутентифицированного пользователя в корневой области.
2. Установите функцию аутентификации на каждом защищенном маршруте.
3. Проверяйте аутентификацию при каждом изменении маршрута.
В качестве альтернативы вы можете установить разрешения для объекта пользователя и назначить каждому маршруту разрешение, а затем проверить разрешение в обратном вызове события.
источник
if (!user && !next.$$route.public)
next.$$route
мне? Я не нахожу ничего в угловом документы , которые описывают аргументы дают в$routeChangeStart
случае, но я полагаю ,next
иcurr
есть какие - то объекты местоположения?$$route
Немного трудно Google.$$route
свойство является частной переменной Angular's. Вы не должны полагаться на это, см., Например: stackoverflow.com/a/19338518/1132101 - если вы это сделаете, ваш код может сломаться при изменении Angular.$route.routes
для создания списка (как в @ thataustin Ответим): получить путь к папке сnext.originalPath
и использовать, чтобы индекс$route.routes
:var auth = $route.routes[next.originalPath]
.Вот как я это сделал, на случай, если это кому-нибудь поможет:
В конфиге я установил
publicAccess
атрибут на нескольких маршрутах, которые я хочу открыть для общего доступа (например, войти или зарегистрироваться):затем в блоке выполнения я устанавливаю прослушиватель на
$routeChangeStart
событие, которое перенаправляет,'/login'
если у пользователя нет доступа или маршрут не является общедоступным:Очевидно, вы могли бы изменить условие
isLoggedIn
на что-нибудь еще ... просто показывая другой способ сделать это.источник
nextLoc.$$route.publicAccess
кстати.$route.routes[nextLoc.originalPath]
, который не использует закрытую переменную.nextLoc && nextLoc.publicAccess
!Я делаю это с помощью перехватчиков. Я создал библиотечный файл, который можно добавить в файл index.html. Таким образом, вы будете иметь глобальную обработку ошибок для вызовов остальных служб, и вам не придется заботиться обо всех ошибках в отдельности. Далее я также вставил свою библиотеку входа в систему basic-auth. Там вы видите, что я также проверяю на ошибку 401 и перенаправляю в другое место. Смотрите lib / ea-basic-auth-login.js
Lib / HTTP-ошибка-handling.js
CSS / HTTP-ошибок handling.css
index.html
Библиотека / еа-основной-AUTH-login.js
Почти то же самое можно сделать для входа в систему. Здесь у вас есть ответ на редирект ($ location.path ("/ login")).
источник
В вашем файле app.js:
источник
С помощью angular-ui-router можно перенаправить на другой экран . Для этого у нас есть метод
$state.go("target_view")
. Например:источник
Если вы не хотите использовать angular-ui-router, но хотели бы, чтобы ваши контроллеры загружались лениво через RequireJS, есть несколько проблем с событием
$routeChangeStart
при использовании ваших контроллеров в качестве модулей RequireJS (загружается лениво).Вы не можете быть уверены, что контроллер будет загружен до того, как
$routeChangeStart
будет запущен - фактически он не будет загружен. Это означает, что вы не можете получить доступ к свойствамnext
маршрута, какlocals
или$$route
потому что они еще не настроены.Пример:
Это означает, что вы не можете проверить права доступа там.
Решение:
Так как загрузка контроллера выполняется с помощью разрешения, вы можете сделать то же самое с проверкой контроля доступа:
Обратите внимание, что вместо использования события
$routeChangeStart
я использую$routeChangeError
источник
источник