Я новичок в AngularJS, и меня немного смущает, как я могу использовать angular- "ui-router" в следующем сценарии:
Я строю веб-приложение, которое состоит из двух разделов. Первый раздел - это домашняя страница с ее представлениями для входа и регистрации, а второй раздел - это панель управления (после успешного входа в систему).
Я создал index.html
для домашнего раздела его угловое приложение и ui-router
конфигурацию для обработки /login
и /signup
просмотра, и есть еще один файл dashboard.html
для раздела приборной панели с его приложением и ui-router
конфигурацией для обработки многих вложенных видов.
Теперь я закончил раздел панели инструментов и не знаю, как объединить эти два раздела с их разными угловыми приложениями. Как я могу сказать домашнему приложению перенаправить приложение на панель инструментов?
источник
Ответы:
Я нахожусь в процессе создания хорошей демонстрации, а также превращения некоторых из этих сервисов в полезный модуль, но вот что я придумала. Это сложный процесс для обхода некоторых предостережений, так что оставайтесь там. Вам нужно будет разбить это на несколько частей.
Взгляни на этот слон .
Во-первых, вам нужен сервис для хранения личности пользователя. Я называю это
principal
. Это может быть проверено, чтобы видеть, вошел ли пользователь в систему, и по запросу, это может разрешить объект, который представляет важную информацию об идентичности пользователя. Это может быть все, что вам нужно, но основными являются отображаемое имя, имя пользователя, возможно, адрес электронной почты и роли, к которым принадлежит пользователь (если это относится к вашему приложению). У принципала также есть методы для проверки ролей.Во-вторых, вам нужна служба, которая проверяет состояние, в которое пользователь хочет перейти, проверяет, вошли ли они в систему (при необходимости; не требуется для входа, сброса пароля и т. Д.), А затем выполняет проверку роли (если ваше приложение). нужно это). Если они не аутентифицированы, отправьте их на страницу входа. Если они прошли проверку подлинности, но не прошли проверку роли, отправьте их на страницу отказа в доступе. Я называю эту услугу
authorization
.Теперь все , что вам нужно сделать , это слушать в
ui-router
«с$stateChangeStart
. Это дает вам возможность проверить текущее состояние, состояние, в которое они хотят перейти, и вставить вашу проверку авторизации. Если это не удается, вы можете отменить переход по маршруту или перейти на другой маршрут.Сложная задача по отслеживанию личности пользователя - поиск, если вы уже прошли аутентификацию (например, вы посещаете страницу после предыдущего сеанса и сохранили токен аутентификации в файле cookie, или, может быть, вы сильно обновили страницу, или упал на URL из ссылки). Из-за того, как это
ui-router
работает, вам нужно выполнить идентификацию один раз перед проверкой аутентификации. Вы можете сделать это, используяresolve
опцию в конфигурации вашего состояния. У меня есть одно родительское состояние для сайта, от которого наследуются все состояния, что заставляет принципал быть разрешенным прежде, чем что-либо еще произойдет.Здесь есть другая проблема ...
resolve
вызывается только один раз. Как только ваше обещание поиска личности будет выполнено, он больше не будет запускать делегат разрешения. Таким образом, мы должны выполнить ваши проверки подлинности в двух местах: один раз в соответствии с вашим обещанием идентификацииresolve
, которое охватывает первый раз, когда ваше приложение загружается, и один раз в$stateChangeStart
если разрешение было выполнено, которое охватывает любое время, когда вы переходите между состояниями.Хорошо, так что мы сделали до сих пор?
Куда мы отправимся отсюда? Ну, вы можете организовать свои состояния в регионы , которые требуют войти. Вы можете потребовать проверку подлинности / авторизованных пользователей, добавляя
data
сroles
этими состояниями (или одного из родителей из них, если вы хотите использовать наследование). Здесь мы ограничиваем ресурс администраторами:Теперь вы можете контролировать состояние за состоянием, что пользователи могут получить доступ к маршруту. Любые другие проблемы? Может быть, меняется только часть представления в зависимости от того, вошли они или нет? Нет проблем. Используйте
principal.isAuthenticated()
или дажеprincipal.isInRole()
с любым из многочисленных способов условного отображения шаблона или элемента.Сначала вставьте
principal
в контроллер или что-то еще, и прикрепите его к области видимости, чтобы вы могли легко использовать его в своем представлении:Показать или скрыть элемент:
И так далее, и так далее, и тому подобное. В любом случае, в вашем примере приложения у вас будет состояние для домашней страницы, которое позволит неаутентифицированным пользователям заходить. У них могут быть ссылки на состояния входа или регистрации или встроенные формы на этой странице. Все, что тебе подходит.
Все страницы панели мониторинга могут наследоваться от состояния, в котором требуется, чтобы пользователи вошли в систему и, скажем, были
User
членами роли. Все авторизационные материалы, которые мы обсуждали, будут исходить оттуда.источник
$location.path
вместо$state.go
.$scope.user
в вашейthen
функции. Вы все еще можете ссылатьсяuser
в своих взглядах; когда это решено, представление будет обновлено.$q.when(angular.noop).then(function(){$state.go('myState')
, все работает как положено. Если я позвоню,$state.go
пока другой переход состояния не будет завершен, он не будет работать (я думаю, что по этой причине он не будет работать).Решения, опубликованные до сих пор, на мой взгляд, излишне сложны. Есть более простой способ. Документация
ui-router
говорит слушать$locationChangeSuccess
и использовать$urlRouter.sync()
для проверки состояния перехода, остановить его или возобновить его. Но даже это на самом деле не работает.Однако вот две простые альтернативы. Выбери один:
Решение 1: прослушивание
$locationChangeSuccess
Вы можете слушать
$locationChangeSuccess
и выполнять некоторую логику, даже асинхронную логику. Основываясь на этой логике, вы можете позволить функции возвращать неопределенное значение, что приведет к тому, что переход состояния продолжится как обычно, или вы можете сделать это$state.go('logInPage')
, если пользователь должен пройти аутентификацию. Вот пример:Имейте в виду, что это на самом деле не препятствует загрузке целевого состояния, но оно перенаправляет на страницу входа, если пользователь не авторизован. Это нормально, так как настоящая защита на сервере, в любом случае.
Решение 2: используя состояние
resolve
В этом решении вы используете
ui-router
функцию разрешения .Вы в основном отклоняете обещание,
resolve
если пользователь не аутентифицирован, а затем перенаправляете его на страницу входа.Вот как это происходит:
В отличие от первого решения, это решение фактически предотвращает загрузку целевого состояния.
источник
state A
. Они нажимают на ссылку, чтобы перейти,protected state B
но вы хотите перенаправить ихlogInPage
. Если нет$timeout
,ui-router
просто остановит все переходы между состояниями, чтобы пользователь застрялstate A
. Параметр$timeout
позволяетui-router
сначала предотвратить первоначальный переход к,protected state B
поскольку разрешение было отклонено, а после этого оно перенаправляет наlogInPage
.authenticate
самом деле вызывается функция?authenticate
Функция @Imray передается в качестве параметраui-router
. Вы не должны называть это сами.ui-router
называет это$stateChangeStart
?Самое простое решение - использовать
$stateChangeStart
иevent.preventDefault()
отменить изменение состояния, когда пользователь не прошел проверку подлинности, и перенаправить его в состояние аутентификации, которое является страницей входа.источник
Я думаю, что вам нужно,
service
чтобы обрабатывать процесс аутентификации (и его хранение).В этом сервисе вам понадобятся несколько основных методов:
isAuthenticated()
login()
logout()
Эта услуга должна быть внедрена в ваши контроллеры каждого модуля:
service.isAuthenticated()
метод). если нет, перенаправить на / логинservice.login()
методХорошим и надежным примером такого поведения является проект angular-app и, в частности, его модуль безопасности , основанный на потрясающем модуле HTTP Auth Interceptor.
Надеюсь это поможет
источник
Я создал этот модуль, чтобы помочь сделать этот процесс кусок пирога
Вы можете делать такие вещи, как:
Или также
Это совершенно новый, но стоит проверить!
https://github.com/Narzerus/angular-permission
источник
Я хотел бы поделиться другим решением, работающим с UI Router 1.0.0.X
Как вы, возможно, знаете, stateChangeStart и stateChangeSuccess теперь устарели. https://github.com/angular-ui/ui-router/issues/2655
Вместо этого вы должны использовать $ transitions http://angular-ui.github.io/ui-router/1.0.0-alpha.1/interfaces/transition.ihookregistry.html
Вот как я этого добился:
Сначала у меня есть и AuthService с некоторыми полезными функциями
Тогда у меня есть эта конфигурация:
Вы можете видеть, что я использую
отмечать состояние доступно только если аутентифицирован.
затем на .run я использую переходы, чтобы проверить состояние autheticated
Я построил этот пример, используя некоторый код, найденный в документации $ transitions. Я довольно новый пользовательский интерфейс роутера, но он работает.
Надеюсь, что это может помочь любому.
источник
Вот как мы вышли из бесконечного цикла маршрутизации и по-прежнему используем
$state.go
вместо$location.path
источник
У меня есть другое решение: это решение прекрасно работает, когда у вас есть только контент, который вы хотите показывать при входе в систему. Определите правило, в котором вы проверяете, вошли ли вы в систему, а не путь к маршрутам из белого списка.
В моем примере я спрашиваю, не вошел ли я в систему, и текущий маршрут, который я хочу направить, не является частью `/ login ', потому что мои маршруты из белого списка следующие
поэтому у меня есть мгновенный доступ к этим двум маршрутам, и каждый другой маршрут будет проверен, если вы находитесь в сети.
Вот весь мой файл маршрутизации для модуля входа
() => { /* code */ }
это синтаксис ES6, используйте вместоfunction() { /* code */ }
источник
Используйте $ http Interceptor
Используя перехватчик $ http, вы можете отправлять заголовки в Back-end или наоборот и выполнять свои проверки таким образом.
Отличная статья о перехватчиках $ http
Пример:
Поместите это в вашу функцию .config или .run.
источник
Сначала вам понадобится сервис, который вы можете внедрить в свои контроллеры, который имеет некоторое представление о состоянии аутентификации приложения. Сохранение деталей аутентификации с локальным хранилищем - достойный способ приблизиться к нему.
Далее вам нужно проверить состояние аутентификации непосредственно перед изменением состояния. Поскольку в вашем приложении есть некоторые страницы, которые должны быть аутентифицированы, а другие нет, создайте родительский маршрут, который проверяет аутентификацию, и сделайте все остальные страницы, которые требуют того же самого, дочерними по отношению к этому родителю.
Наконец, вам понадобится какой-то способ узнать, может ли ваш вошедший в систему пользователь выполнить определенные операции. Это может быть достигнуто путем добавления функции 'can' к вашей службе аутентификации. Может принимать два параметра: - действие - требуется - (т. Е. «Manage_dashboards» или «create_new_dashboard») - объект - необязательно - объект, над которым выполняется операция. Например, если у вас был объект панели мониторинга, вы можете проверить, есть ли dashboard.ownerId === loggedInUser.id. (Конечно, информация, передаваемая от клиента, никогда не должна быть доверенной, и вы всегда должны проверять это на сервере, прежде чем записывать ее в базу данных).
** ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: приведенный выше код является псевдокодом и не дает никаких гарантий **
источник