Jestem nowy w AngularJS i jestem trochę zdezorientowany, jak mogę używać angular-„ui-router” w następującym scenariuszu:
Buduję aplikację internetową, która składa się z dwóch części. Pierwsza sekcja to strona główna z widokami logowania i rejestracji, a druga sekcja to pulpit nawigacyjny (po udanym zalogowaniu).
Utworzyłem index.html
sekcję główną z aplikacją kątową i ui-router
konfiguracją do obsługi /login
i /signup
widoków, a dashboard.html
dla sekcji deski rozdzielczej z aplikacją i innym plikiem jest inny plikui-router
konfiguracją do obsługi wielu widoków podrzędnych.
Teraz skończyłem sekcję deski rozdzielczej i nie wiem, jak połączyć te dwie sekcje z ich różnymi aplikacjami kątowymi. Jak mogę powiedzieć aplikacji domowej, aby przekierowała do aplikacji deski rozdzielczej?
źródło
Odpowiedzi:
Jestem w trakcie tworzenia ładniejszej wersji demo, a także porządkowania niektórych z tych usług w użytecznym module, ale oto co wymyśliłem. Jest to złożony proces obejścia niektórych zastrzeżeń, więc trzymaj się. Musisz to rozbić na kilka części.
Spójrz na to słowo .
Po pierwsze, potrzebujesz usługi do przechowywania tożsamości użytkownika. Nazywam to
principal
. Można to sprawdzić, czy użytkownik jest zalogowany, a na żądanie może rozwiązać obiekt reprezentujący niezbędne informacje o tożsamości użytkownika. Może to być wszystko, czego potrzebujesz, ale najważniejsze to nazwa wyświetlana, nazwa użytkownika, ewentualnie e-mail i role, do których użytkownik należy (jeśli dotyczy to Twojej aplikacji). Principal ma również metody sprawdzania ról.Po drugie, potrzebujesz usługi, która sprawdza stan, w którym użytkownik chce przejść, upewnia się, że jest zalogowany (jeśli to konieczne; nie jest konieczne do logowania, resetowania hasła itp.), A następnie sprawdza rolę (jeśli Twoja aplikacja jest zalogowana) potrzebuje tego). Jeśli nie są uwierzytelnione, wyślij je na stronę logowania. Jeśli są uwierzytelnione, ale nie sprawdzają roli, wyślij je na stronę, na której odmówiono dostępu. Dzwonię do tej usługi
authorization
.Teraz wszystko, co musisz zrobić, to słuchać na
ui-router
„s$stateChangeStart
. Daje to szansę na sprawdzenie bieżącego stanu, stanu, do którego chcą przejść, i wstawienie kontroli autoryzacji. Jeśli się nie powiedzie, możesz anulować zmianę trasy lub zmienić inną trasę.Trudną częścią śledzenia tożsamości użytkownika jest sprawdzenie go, jeśli już go uwierzytelniłeś (powiedzmy, że odwiedzasz stronę po poprzedniej sesji i zapisałeś token uwierzytelnienia w pliku cookie, a może mocno odświeżyłeś stronę lub upuszczony na adres URL z linku). Ze względu na sposób
ui-router
działania konieczne jest jednokrotne rozpoznanie tożsamości przed sprawdzeniem autoryzacji. Możesz to zrobić za pomocąresolve
opcji w konfiguracji stanu. Mam jeden stan nadrzędny dla witryny, z której dziedziczą wszystkie stany, co zmusza zasadę do rozwiązania, zanim cokolwiek innego się wydarzy.Jest tu inny problem ...
resolve
zostaje wywołany tylko raz. Po wypełnieniu obietnicy wyszukiwania tożsamości nie uruchomi ona ponownie delegata rozwiązania. Musimy więc przeprowadzić weryfikację uwierzytelnienia w dwóch miejscach: raz, zgodnie z obietnicą tożsamości, wresolve
której dotyczy to pierwszego uruchomienia aplikacji, i raz,$stateChangeStart
jeśli rozdzielczość została wykonana, co obejmuje każdą nawigację po stanach.OK, więc co do tej pory zrobiliśmy?
Dokąd zmierzamy? Cóż, można organizować swoje stany w regionach, które wymagają podpisania w. Można wymagać uwierzytelnionych / autoryzowanych użytkowników, dodając
data
zroles
tych państw (lub rodzic z nich, jeśli chcesz korzystać z dziedziczenia). Tutaj ograniczamy zasób do administratorów:Teraz możesz kontrolować stan po stanie, którzy użytkownicy mogą uzyskać dostęp do trasy. Jakieś inne obawy? Może zmieniając tylko część widoku w zależności od tego, czy są zalogowani? Nie ma problemu. Użyj
principal.isAuthenticated()
lubprincipal.isInRole()
z jednego z wielu sposobów warunkowego wyświetlania szablonu lub elementu, z nich.Najpierw wstrzyknij
principal
do kontrolera lub cokolwiek innego i przyklej go do lunety, abyś mógł go łatwo używać w swoim widoku:Pokaż lub ukryj element:
Itd., Itd. Itd. Tak czy inaczej, w twojej przykładowej aplikacji miałbyś stan strony głównej, który pozwalałby odwiedzać nieuwierzytelnionym użytkownikom. Mogą mieć linki do stanów logowania lub rejestracji albo mieć wbudowane formularze na tej stronie. Cokolwiek Ci odpowiada.
Wszystkie strony panelu kontrolnego mogą dziedziczyć po stanie, który wymaga zalogowania użytkowników i, powiedzmy, bycia
User
członkiem roli. Stąd płyną wszystkie omówione przez nas kwestie związane z autoryzacją.źródło
$location.path
zamiast$state.go
.$scope.user
twojejthen
funkcji. Nadal możesz odwoływać sięuser
w swoich poglądach; po rozwiązaniu widok zostanie zaktualizowany.$q.when(angular.noop).then(function(){$state.go('myState')
wszystko działa zgodnie z oczekiwaniami. Jeśli zadzwonię,$state.go
gdy przejście innego stanu nie zostanie zakończone, to nie zadziała (myślę, że to jest powód, dla którego nie zadziała).Dotychczasowe rozwiązania są, moim zdaniem, niepotrzebnie skomplikowane. Jest prostszy sposób. Dokumentacja
ui-router
mówi słuchać$locationChangeSuccess
i wykorzystanie$urlRouter.sync()
sprawdzić przejście stanu, zatrzymanie go lub ją wznowić. Ale nawet to tak naprawdę nie działa.Oto jednak dwie proste alternatywy. Wybierz jedno:
Rozwiązanie 1: słuchanie dalej
$locationChangeSuccess
Możesz słuchać
$locationChangeSuccess
i wykonywać logikę, nawet logikę asynchroniczną. W oparciu o tę logikę możesz pozwolić, aby funkcja zwróciła niezdefiniowaną, co spowoduje, że przejście stanu będzie kontynuowane jak zwykle, lub możesz to zrobić$state.go('logInPage')
, jeśli użytkownik musi zostać uwierzytelniony. Oto przykład:Należy pamiętać, że tak naprawdę nie zapobiega to ładowaniu stanu docelowego, ale przekierowuje na stronę logowania, jeśli użytkownik jest nieautoryzowany. To jest w porządku, ponieważ prawdziwa ochrona jest zresztą na serwerze.
Rozwiązanie 2: za pomocą stanu
resolve
W tym rozwiązaniu korzystasz z
ui-router
funkcji rozpoznawania .Zasadniczo odrzucasz obietnicę,
resolve
jeśli użytkownik nie jest uwierzytelniony, a następnie przekierowujesz go na stronę logowania.Oto jak to wygląda:
W przeciwieństwie do pierwszego rozwiązania, to rozwiązanie faktycznie zapobiega ładowaniu stanu docelowego.
źródło
state A
. Klikają link, aby przejść do,protected state B
ale chcesz je przekierowaćlogInPage
. Jeśli nie$timeout
,ui-router
po prostu zatrzyma wszystkie przejścia między stanami, aby użytkownik utknąłstate A
.$timeout
Pozwalaui-router
najpierw zapobiec początkową przejściaprotected state B
ponieważ postanowienie zostało odrzucone, a potem zrobił, to przekierowujelogInPage
.authenticate
faktycznie wywoływana funkcja?authenticate
Funkcja @Imray jest przekazywana jako parametr doui-router
. Nie musisz nazywać tego sam.ui-router
nazywa to.$stateChangeStart
?Najprostszym rozwiązaniem jest użycie
$stateChangeStart
ievent.preventDefault()
aby anulować zmianę stanu, gdy użytkownik nie jest uwierzytelniony i przekierować go do auth państwa, które jest strona logowania.źródło
Myślę, że potrzebujesz proces
service
obsługi uwierzytelnienia (i jego przechowywania).W tej usłudze potrzebujesz kilku podstawowych metod:
isAuthenticated()
login()
logout()
Tę usługę należy wprowadzić do kontrolerów każdego modułu:
service.isAuthenticated()
metoda). jeśli nie, przekieruj na / loginservice.login()
metodyDobrym i solidnym przykładem tego zachowania jest aplikacja kątowa projektu, a zwłaszcza jej moduł bezpieczeństwa oparty na niesamowitym module przechwytującym HTTP Auth
Mam nadzieję że to pomoże
źródło
Stworzyłem ten moduł, aby ten proces był jak bułka z masłem
Możesz robić takie rzeczy jak:
Lub też
Jest nowy, ale warto go sprawdzić!
https://github.com/Narzerus/angular-permission
źródło
Chciałem udostępnić inne rozwiązanie współpracujące z routerem interfejsu użytkownika 1.0.0.X
Jak zapewne wiesz, stateChangeStart i stateChangeSuccess są teraz przestarzałe. https://github.com/angular-ui/ui-router/issues/2655
Zamiast tego powinieneś użyć $ transitions http://angular-ui.github.io/ui-router/1.0.0-alpha.1/interfaces/transition.ihookregistry.html
Oto jak to osiągnąłem:
Najpierw mam i AuthService z kilkoma przydatnymi funkcjami
Następnie mam tę konfigurację:
Widać, że używam
aby oznaczyć stan jako dostępny tylko wtedy, gdy jest uwierzytelniony.
następnie na .run używam przejść, aby sprawdzić stan uwierzytelnienia
Buduję ten przykład przy użyciu kodu znalezionego w dokumentacji $ Transitions. Jestem całkiem nowy z routerem interfejsu użytkownika, ale działa.
Mam nadzieję, że może pomóc każdemu.
źródło
Oto jak wydostaliśmy się z nieskończonej pętli routingu i nadal używaliśmy
$state.go
zamiast$location.path
źródło
Mam inne rozwiązanie: to rozwiązanie działa idealnie, gdy masz tylko treść, którą chcesz wyświetlić, gdy jesteś zalogowany. Zdefiniuj regułę, w której sprawdzasz, czy jesteś zalogowany, a nie ścieżkę do białej listy tras.
W moim przykładzie pytam, czy nie jestem zalogowany, a bieżąca trasa, którą chcę trasować, nie jest częścią `/ login ', ponieważ moje trasy na białej liście są następujące
więc mam natychmiastowy dostęp do tych dwóch tras, a każda inna trasa zostanie sprawdzona, jeśli jesteś online.
Oto mój cały plik routingu dla modułu logowania
() => { /* code */ }
jest składnią ES6, użyj zamiast tegofunction() { /* code */ }
źródło
Użyj $ http Interceptor
Za pomocą przechwytywacza $ http możesz wysyłać nagłówki do zaplecza lub na odwrót i przeprowadzać kontrole w ten sposób.
Świetny artykuł na temat $ http przechwytujących
Przykład:
Umieść to w swojej funkcji .config lub .run.
źródło
Najpierw potrzebujesz usługi, którą możesz wstrzyknąć do kontrolerów, która ma pewne pojęcie o stanie uwierzytelnienia aplikacji. Utrzymywanie danych uwierzytelniających w lokalnej pamięci jest dobrym sposobem na zbliżenie się do nich.
Następnie musisz sprawdzić stan uwierzytelnienia tuż przed zmianą stanu. Ponieważ aplikacja zawiera niektóre strony, które wymagają uwierzytelnienia, a inne nie, utwórz trasę nadrzędną, która sprawdza uwierzytelnianie, i spraw, aby wszystkie inne strony, które tego wymagają, były potomkami tego rodzica.
Na koniec będziesz potrzebować sposobu, aby stwierdzić, czy aktualnie zalogowany użytkownik może wykonywać określone operacje. Można to osiągnąć, dodając funkcję „można” do usługi uwierzytelniania. Może przyjmować dwa parametry: - działanie - wymagane - (tj. „Manage_dashboards” lub „create_new_dashboard”) - obiekt - opcjonalnie - obiekt jest obsługiwany. Na przykład, jeśli masz obiekt deski rozdzielczej, możesz sprawdzić, czy dashboard.ownerId === loggedInUser.id. (Oczywiście informacje przekazywane od klienta nigdy nie powinny być zaufane i zawsze należy je zweryfikować na serwerze przed zapisaniem ich w bazie danych).
** ZASTRZEŻENIE: Powyższy kod jest pseudokodem i nie ma żadnych gwarancji **
źródło