Решения, опубликованные до сих пор, на мой взгляд, излишне сложны. Есть более простой способ. документация ui-router
говорит, что слушайте $locationChangeSuccess
и используйте $urlRouter.sync()
, чтобы проверить переход состояния, остановить его или возобновить. Но даже это на самом деле не работает.
Однако, здесь есть две простые альтернативы. Выберите один:
$locationChangeSuccess
Вы можете слушать $locationChangeSuccess
и выполнять некоторую логику, даже асинхронную логику. Основываясь на этой логике, вы можете позволить функции возвращать неопределенное значение, что приведет к продолжению перехода состояния в нормальном режиме, или вы можете сделать $state.go('logInPage')
, если пользователь должен пройти аутентификацию. Вот пример:
angular.module('App', ['ui.router'])
// In the run phase of your Angular application
.run(function($rootScope, user, $state) {
// Listen to '$locationChangeSuccess', not '$stateChangeStart'
$rootScope.$on('$locationChangeSuccess', function() {
user
.logIn()
.catch(function() {
// log-in promise failed. Redirect to log-in page.
$state.go('logInPage')
})
})
})
Имейте в виду, что это на самом деле не препятствует загрузке целевого состояния, но оно перенаправляет на страницу входа в систему, если пользователь не авторизован. Это нормально, так как настоящая защита на сервере, во всяком случае.
resolve
В этом решении вы используете ui-router
функцию разрешения .
Вы в основном отклоняете обещание в resolve
, если пользователь не прошел проверку подлинности, а затем перенаправляете его на страницу входа.
Вот как это происходит:
angular.module('App', ['ui.router'])
.config(
function($stateProvider) {
$stateProvider
.state('logInPage', {
url: '/logInPage',
templateUrl: 'sections/logInPage.html',
controller: 'logInPageCtrl',
})
.state('myProtectedContent', {
url: '/myProtectedContent',
templateUrl: 'sections/myProtectedContent.html',
controller: 'myProtectedContentCtrl',
resolve: { authenticate: authenticate }
})
.state('alsoProtectedContent', {
url: '/alsoProtectedContent',
templateUrl: 'sections/alsoProtectedContent.html',
controller: 'alsoProtectedContentCtrl',
resolve: { authenticate: authenticate }
})
function authenticate($q, user, $state, $timeout) {
if (user.isAuthenticated()) {
// Resolve the promise successfully
return $q.when()
} else {
// The next bit of code is asynchronously tricky.
$timeout(function() {
// This code runs after the authentication promise has been rejected.
// Go to the log-in page
$state.go('logInPage')
})
// Reject the authentication promise to prevent the state from loading
return $q.reject()
}
}
}
)
В отличие от первого решения, это решение фактически предотвращает загрузку целевого состояния.
Если вы можете себе позволить дождаться исключение, подключите управляемый и собственный отладчик (смешанный сеанс отладки) и установите управляемый отладчик на прерывание при возникновении AccessViolationException
. Управляемый отладчик прервет процесс, когда обнаружит необработанное исключение, и тогда вы сможете увидеть собственный стек вызовов.