2014-11-18 11 views
9

Załóżmy, że mam 4 trasy - 2 wymagają zalogowania użytkownika, 2 nie. Moja aplikacja startowych wygląda następująco:Jak sprawdzić logowanie lub inny status przed uruchomieniem trasy w Angular z 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'}); 

Trasy /open1/open2 i są otwarte dla wszystkich, podczas trasy /secure1 i /secure2 wymagać od użytkownika, aby zalogować się, a jeśli nie, podjąć pewne działania, na przykład przekieruj do logowania lub uruchom ostrzeżenie. Mogę określić stan użytkownika za pomocą usługi i wywołania Auth, np. Auth.isLogin(). Więc wynik będzie:

  • zamiar /open1 i /open2 zawsze iść do szablonu i kontrolera deklarowanej powyżej
  • jeśli Auth.isLogin() zwraca true, /secure1 i /secure2 iść do wyżej zadeklarowana szablonu i kontrolera
  • jeśli Auth.isLogin() zwraca false, /secure1 i /secure2 wykonaj inne czynności, np. $location.path('/login')

I mógłby put logikę w Secure1 i Secure2 kontrolerów, która sprawdza, ale to jest powtarzalne i miesza się obowiązków, sprawia, że ​​trudniej testować itp

Czy istnieje sposób, że mogę użyj $routeProvider, aby zadeklarować "sprawdź tę trasę i tę trasę, a jeśli nie, przekieruj"? Myślałem o użyciu w pewnym sensie resolve, ale nie jestem do końca pewien, jak to zrobić (dokumenty na temat resolve nie są bardzo jasne i kilka pomocnych przykładów).

EDIT:

na podstawie poniższych odpowiedzi, wydaje się, istnieją trzy filozofie w ten sposób:

Druga opcja jest tym, co zasugerowali ci dwaj respondenci.

Odpowiedz

12

jak w moim powyższych uwag, są 3 różne ścieżki (plus zdolność używać dyrektywy, jeśli chcesz kontrolować ją w szablonach html). Skończyło się następujące

https://midgetontoes.com/angularjs-check-user-login/

który zasadniczo jest następująca:

$routeProvider.when('/secure', { 
    templateUrl: '/secure.html', 
    controller: 'Secure', 
    resolve:{ 
     loggedIn:onlyLoggedIn 
    } 
}); 

A potem 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; 
}; 

Proste, działa jak czar. Jeśli kiedykolwiek będę potrzebował dyrektywy, wciągnę ten utwór do służby.

+0

Czy możesz wspomnieć, gdzie umieścić var ​​onlyLoggedIn, jak w jakim zakresie? Jestem dla niego bardzo nowy. @deitch –

+0

@AayushKumarSingha Właśnie ogłaszam, że jest to funkcja zmiennej lokalnej w moim app.js, a następnie odwołuję ją do mojego '$ routeProvider'. Ale może być w dowolnym miejscu, ponieważ zawsze można "wymagać()" lub w inny sposób go zawrzeć. – deitch

+6

Twój adres URL jest już martwy. – Denny

2

miałem ten sam problem i zrobiłem to w ten sposób:

var app = angular.module('myModule',["ui-bootstrap"]); 

A następnie słuchać na locationChange w aplikacji (będzie to również wywołać onEnter strony)

app.run(function ($rootScope, $location, $cookieStore) { 
$rootScope.$on("$locationChangeStart", function (event, next, current) { 
    //Here you can check whatever you want (servercall, cookie...) 
}); 
} 

I Mam nadzieję że to pomoże!

+0

To nie jest zły plan, ale muszę dodać logikę do trasy w programie obsługi zdarzeń i jak zatrzymać konkretną trasę przed uruchomieniem? – deitch

+0

Dodałem funkcję zatrzymania "rzutu" "; które zatrzyma całą aktywność javascript. I zrobił przekierowanie do strony logowania. W funkcji sprawdzam, czy $ location.path == "/ signin"; –

+0

Myślę, że to zadziała. Czy nic w '$ routeProvider' nie może pomóc? – deitch

4

This blog post dotyczy uwierzytelniania użytkownika w AngularJS przy użyciu dyrektyw.

Usługa $ route emituje $ routeChangeStart przed zmianą trasy.

Jeśli nie używasz dyrektyw, możesz złapać to wydarzenie, wywołując app.run (możesz umieścić je po kodzie, w którym definiujesz trasy [app.config]). Np

pełnego ujawnienia użyć ui.router i to jest przystosowany kod z $stateChangeStart używać w aplikacji

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'); 
     } 
    }); 
}]); 
+0

Czy mogę zatem użyć zdarzenia $ $ routeChangeStart', aby uchwycić i zapobiec kontynuacji? Nadal potrzebowałbym znać ścieżki i wolałbym to zrobić w '$ routeProvider.when'), jeśli mogę, ale to by działało. Jest to podobne do odpowiedzi @JasonvanderZeeuw poniżej. Przeczytam wpis na blogu, dziękuję – deitch

+0

@deszę polecam [router AngularUI] (http://angular-ui.github.io/ui-router/site/), ponieważ używa stanów zamiast adresów URL. Na przykład stan może mieć wartość _secure.report_ lub _secure.list_, a adres URL to _/report_ lub _/list_, a następnie sprawdzać tylko, czy stan zawiera _secure_ w nazwie, bez znajomości dokładnych linków. – vjancic

+0

Sprawdzę to po przeczytaniu posta na blogu. – deitch

Powiązane problemy