2015-01-12 6 views
17

Buduję aplikację w systemie Ionic i zacząłem korzystać z metody uwierzytelniania Firebase. Do tej pory udało mi się poprawnie skonfigurować Login przez Twittera (mogę się zalogować i wylogować).Jak obsługiwać stany po zalogowaniu (Ionic, Firebase, AngularJS)?

Jak jednak ustawić stany jonowego szkieletu tak, aby tylko określone stany (a tym samym strony) były wyświetlane po zalogowaniu i innych po wylogowaniu? Dotychczasowy kod jest pokazany poniżej.

Idealnie byłoby mam coś takiego zmiennej:

AuthRequired: true 

Jak to zrobić i co się nazywa?

app.js

// Ionic Starter App 

// angular.module is a global place for creating, registering and retrieving Angular modules 
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html) 
// the 2nd parameter is an array of 'requires' 
// 'starter.services' is found in services.js 
// 'starter.controllers' is found in controllers.js 
angular.module('starter', ['ionic', 'ngCordova', 'firebase', 'firebase.utils', 'starter.controllers', 'starter.services', 'starter.config', 'starter.auth']) 

.run(function($ionicPlatform, Auth, $rootScope) { 


    $ionicPlatform.ready(function() { 
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard 
    // for form inputs) 
    if (window.cordova && window.cordova.plugins.Keyboard) { 
     cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); 
    } 
    if (window.StatusBar) { 
     // org.apache.cordova.statusbar required 
     StatusBar.styleDefault(); 
    } 
    }); 



    //stateChange event 
    $rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams){ 
     if (toState.authRequired && !Auth.isAuthenticated()){ //Assuming the AuthService holds authentication logic 
     // User isn’t authenticated 
     $state.transitionTo("login"); 
     event.preventDefault(); 
     } 
    }); 





}) 

.config(function($stateProvider, $urlRouterProvider) { 

    // Ionic uses AngularUI Router which uses the concept of states 
    // Learn more here: https://github.com/angular-ui/ui-router 
    // Set up the various states which the app can be in. 
    // Each state's controller can be found in controllers.js 
    $stateProvider 

    // setup an abstract state for the tabs directive 
    .state('tab', { 
    url: "/tab", 
    abstract: true, 
    templateUrl: "templates/tabs.html" 
    }) 

    // Each tab has its own nav history stack: 

    .state('tab.dash', { 
    url: '/dash', 
    views: { 
     'tab-dash': { 
     templateUrl: 'templates/tab-dash.html', 
     controller: 'DashCtrl', 
     authRequired: true 
     }, 
    } 
    }) 

    .state('tab.chats', { 
     url: '/chats', 
     views: { 
     'tab-chats': { 
      templateUrl: 'templates/tab-chats.html', 
      controller: 'ChatsCtrl', 
      authRequired: true 
     } 
     } 
    }) 
    .state('tab.chat-detail', { 
     url: '/chats/:chatId', 
     views: { 
     'tab-chats': { 
      templateUrl: 'templates/chat-detail.html', 
      controller: 'ChatDetailCtrl', 
      authRequired: true 
     } 
     } 
    }) 

    .state('tab.friends', { 
     url: '/friends', 
     views: { 
     'tab-friends': { 
      templateUrl: 'templates/tab-friends.html', 
      controller: 'FriendsCtrl', 
      authRequired: true 
     } 
     } 
    }) 
    .state('tab.friend-detail', { 
     url: '/friend/:friendId', 
     views: { 
     'tab-friends': { 
      templateUrl: 'templates/friend-detail.html', 
      controller: 'FriendDetailCtrl', 
      authRequired: true 
     } 
     } 
    }) 

    .state('tab.account', { 
    url: '/account', 
    views: { 
     'tab-account': { 
     templateUrl: 'templates/tab-account.html', 
     controller: 'AccountCtrl', 
      authRequired: true 
     } 
    } 
    }) 

    .state('tab.example', { 
    url: '/example', 
    views: { 
     'tab-example': { 
     templateUrl: 'templates/tab-example.html', 
     controller: 'ExampleCtrl', 
      authRequired: true 
     } 
    } 
    }) 


    .state('tab.overview', { 
    url: '/overview', 
    views: { 
     'tab-overview': { 
     templateUrl: 'templates/tab-overview.html', 
     controller: 'OverviewCtrl', 
      authRequired: true 
     } 
    } 
    }) 

    .state('tab.login', { 
    url: '/login', 
    views: { 
     'tab-login': { 
     templateUrl: 'templates/tab-login.html', 
     controller: 'LoginCtrl', 
      authRequired: true 
     } 
    } 
    }); 

    // if none of the above states are matched, use this as the fallback 
    $urlRouterProvider.otherwise('/tab/dash'); 

}) 

index.html

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> 
    <title></title> 

    <link href="lib/ionic/css/ionic.css" rel="stylesheet"> 
    <link href="css/style.css" rel="stylesheet"> 

    <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above 
    <link href="css/ionic.app.css" rel="stylesheet"> 
    --> 

    <!-- ionic/angularjs js --> 
    <script src="lib/ionic/js/ionic.bundle.js"></script> 


    <!-- firebase and simple login --> 
    <script src="https://cdn.firebase.com/libs/angularfire/0.9.1/angularfire.min.js"></script> 
    <script src="https://cdn.firebase.com/js/client/2.0.4/firebase.js"></script> 


    <!-- cordova script (this will be a 404 during development) --> 
    <script src="lib/ngCordova/dist/ng-cordova.js"></script> 
    <script src="cordova.js"></script> 

    <!-- your app's js --> 
    <script src="js/app.js"></script> 
    <script src="js/controllers.js"></script> 
    <script src="js/services.js"></script> 



    </head> 
    <body ng-app="starter"> 
    <!-- 
     The nav bar that will be updated as we navigate between views. 
    --> 
    <ion-nav-bar class="bar-stable"> 
     <ion-nav-back-button> 
     </ion-nav-back-button> 
    </ion-nav-bar> 
    <!-- 
     The views will be rendered in the <ion-nav-view> directive below 
     Templates are in the /templates folder (but you could also 
     have templates inline in this html file if you'd like). 


    --> 

    <ion-nav-view animation="slide-left-right"></ion-nav-view> 



    </body> 
</html> 
+0

Używasz router ui lub oficjalnego ngRouter? Dla siebie używam routera Ui iw każdym stanie mogę zapisywać własne dane, takie jak boolean o nazwie "public", który decyduje, czy odpowiedni stan wymaga uwierzytelnienia, czy nie. Mogę podać ci bardziej szczegółowe informacje, jeśli chcesz czegoś takiego. –

+0

Witam Himmet. Szczerze mówiąc nie wiem, myślę, że standardowy, który pochodzi z Ionic Framework. Tak, proszę, podziel się swoimi metodami! – AMG

+0

Jestem w stanie uzyskać akceptowaną odpowiedź do pracy. Jedną z różnic w moim kodzie jest to, że mam "authRequired" jako właściwość stanu i nie zagnieżdżam się w widoku stanu. W przeciwnym razie wydawało mi się, że musisz zmodyfikować "toState.authRequire", aby sprawdzić wewnątrz toState.view. – liampronan

Odpowiedz

15

Jesteś prawie tam. Wszystko, czego potrzebujesz, to sprawdzenie, czy twoje stany są oznaczone właściwością niestandardową "AuthRequired" i nasłuchiwanie zdarzenia $ stateChangeStart w celu sprawdzenia uwierzytelnienia. To zdarzenie jest uruchamiane za każdym razem, gdy poruszasz się w aplikacji.

.run(function($ionicPlatform, AuthService) { 
     //ionic init code  

     //stateChange event 
     $rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams){ 
     if (toState.authRequired && !AuthService.isAuthenticated()){ //Assuming the AuthService holds authentication logic 
     // User isn’t authenticated 
     $state.transitionTo("login"); 
     event.preventDefault(); 
     } 
    }); 
} 

.state('tab.dash', { 
    url: '/dash', 
    views: { 
     'tab-dash': { 
     templateUrl: 'templates/tab-dash.html', 
     controller: 'DashCtrl', 
     authRequired: true 
     } 
    } 
    }) 

    .state('tab.chats', { 
     url: '/chats', 
     views: { 
     'tab-chats': { 
      templateUrl: 'templates/tab-chats.html', 
      controller: 'ChatsCtrl', 
      authRequired: true 
     } 
     } 
    }) 

Najlepszym miejscem do obsługi zdarzenia $ stateChangeStart będzie aplikacja uruchamiana.

+0

Dzięki za odpowiedź. Nie rozumiem dokładnie, gdzie i jak umieścić stateChangeStart? – AMG

+0

@ AMG stateChange event handler musi zostać umieszczony w funkcji run, w której zainicjujesz ionic. Funkcja run jest najbliższa głównej metodzie w kanciastej, która jest wykonywana po załadowaniu aplikacji. Zaktualizowałem kod dla ciebie – Karthik

+0

Dzięki za aktualizację. Wydaje się, że nie działa to dla mnie, ponieważ mam moje stany w .config. AuthService to Auth? – AMG

0

Aby odnieść sukces odczytać wartość używając:

toState.authRequired 

Proszę przejść authRequired: true wewnątrz .state zamiast views.

2

Miałem ten sam problem, co twój! Zobacz, jak to rozwiązałem!

app.js

angular.module('app', ['ionic','firebase', 'app.controllers', 'app.routes', 'app.directives','app.services','app.filters',]) 

.run(function($ionicPlatform, $rootScope, $state) { 
    $ionicPlatform.ready(function() { 
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard 
    // for form inputs) 
    if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) { 
     cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); 
     cordova.plugins.Keyboard.disableScroll(true); 
    } 
    if (window.StatusBar) {// 
     // org.apache.cordova.statusbar required 
     StatusBar.styleDefault(); 
    } 
    }); 

    //stateChange event 
    $rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams){ 
    var user = firebase.auth().currentUser; 
    if (toState.authRequired && !user){ //Assuming the AuthService holds authentication logic 
     // User isn’t authenticated 
     $state.transitionTo("login"); 
     event.preventDefault(); 
    } 
    }); 
    // Initialize Firebase Here 

}) 

routes.js

angular.module('app.routes', ['ionicUIRouter']) 

.config(function($stateProvider, $urlRouterProvider) { 

    $stateProvider 

    .state('login', { 
    url: '/login', 
    templateUrl: 'templates/login.html', 
    controller: 'loginCtrl' 
    }) 

.state('menu', { 
    url: '/menu', 
    templateUrl: 'templates/menu.html', 
    abstract:true, 
    controller: 'menuCtrl' 
    }) 

    .state('menu.dash', { 
    url: '/contas', 
    templateUrl: 'templates/dash.html', 
    controller: 'contasCtrl', 
    authRequired: true 
    }) 

$urlRouterProvider.otherwise('/login') 

}); 
Powiązane problemy