2014-09-16 7 views
10

मैं AngularUI राउटर के साथ कुछ प्रमाणीकरण करने की कोशिश कर रहा हूं। $urlRouter.sync() बिल्कुल वैसा ही दिखता है जो मुझे चाहिए। हालांकि, यह केवल तब उपलब्ध है जब मैं $locationChangeSuccess को रोकता हूं। लेकिन जब मैं ऐसा करता हूं, $state.current.name खाली है, जबकि मैं चाहता हूं कि यह वर्तमान स्थिति हो।

यहाँ मेरी कोड अब तक बताया गया है:

$rootScope.$on('$locationChangeSuccess', function(event, next, nextParams) { 
    event.preventDefault(); 
    if ($state.current.name === 'login') { 
    return userService.isAuthenticated().then(function(response) { 
     var authenticated; 
     authenticated = response.authenticated; 
     return alert(authenticated); 
    }); 
    } 
}); 

मैं गलत क्या कर रहा है के रूप में किसी भी संकेत दिए गए?

+0

अं ... क्या '$ stateChangeSuccess' के बारे में? – naeramarth7

+0

तब मैं 'urlRouter.sync()' – Shamoon

+0

'$ state.current.name' का उपयोग नहीं कर सकता केवल आरंभिक पृष्ठ लोड पर खाली होगा। उसके बाद ट्रिगर किए गए किसी भी राज्य परिवर्तन का राज्य नाम होगा। यदि आपको केवल प्रमाणीकरण लागू करने की आवश्यकता है, तो '$ stateChangeStart' पर सुनें - आपको' urlRouter.sync() 'के बारे में चिंता करने की आवश्यकता नहीं है। इसके आसपास कई उदाहरण हैं जो दर्शाते हैं। – IanB

उत्तर

34

मैं और अधिक "UI-Router रास्ता" जाने का सुझाव दूंगा। हमें $rootScope.$on('$stateChangeStart' ईवेंट का उपयोग करना चाहिए जहां $state.current उचित रूप से प्रदान किया जाएगा। यहाँ a working example

के सरल (लेकिन अनुभवहीन नहीं) समाधान है, जो बाद में किसी भी हद तक बढ़ाया जा सकता है का अवलोकन करते है। इसके अलावा, अगर आप इस दृष्टिकोण पसंद करेंगे, यहाँ और अधिक व्यापक कार्यान्वयन है:

.factory('userService', function ($timeout, $q) { 

    var user = undefined; 

    return { 
     // async way how to load user from Server API 
     getAuthObject: function() { 
      var deferred = $q.defer(); 

      // later we can use this quick way - 
      // - once user is already loaded 
      if (user) { 
       return $q.when(user); 
      } 

      // server fake call, in action would be $http 
      $timeout(function() { 
       // server returned UN authenticated user 
       user = {isAuthenticated: false }; 
       // here resolved after 500ms 
       deferred.resolve(user) 
      }, 500) 

      return deferred.promise; 
     }, 

     // sync, quick way how to check IS authenticated... 
     isAuthenticated: function() { 
      return user !== undefined 
       && user.isAuthenticated; 
     } 
    };  
}) 

तो, हम async का उपयोग (यहाँ $timeout) को: angular ui-router login authentication

सबसे पहले, चलो हमारे उपयोगकर्ता सेवा इस तरह परिभाषित किया गया है चलो लोड user ऑब्जेक्ट एक सर्वर बनाते हैं। हमारे उदाहरण में इसकी संपत्ति {isAuthenticated: false } होगी, जिसका उपयोग यह प्रमाणित करने के लिए किया जाएगा कि प्रमाणित है या नहीं।

सिंक विधि isAuthenticated() भी है, जब तक उपयोगकर्ता लोड और अनुमति नहीं देता है - हमेशा false देता है।

और वह '$stateChangeStart' घटना के बारे में हमारी श्रोता होगा:

.run(['$rootScope', '$state', 'userService', 
function ($rootScope, $state, userService) { 

    $rootScope.$on('$stateChangeStart', function (event, toState, toParams 
                 , fromState, fromParams) {  
     // if already authenticated... 
     var isAuthenticated = userService.isAuthenticated(); 
     // any public action is allowed 
     var isPublicAction = angular.isObject(toState.data) 
          && toState.data.isPublic === true;  

     if (isPublicAction || isAuthenticated) { 
      return; 
     } 

     // stop state change 
     event.preventDefault(); 

     // async load user 
     userService 
      .getAuthObject() 
      .then(function (user) { 

       var isAuthenticated = user.isAuthenticated === true; 

       if (isAuthenticated) { 
       // let's continue, use is allowed 
       $state.go(toState, toParams) 
       return; 
       }  
       // log on/sign in... 
       $state.go("login"); 
      }) 
     ... 

क्या हम पहले जाँच कर रहे हैं, यदि उपयोगकर्ता पहले से ही भरा हुआ है और प्रमाणीकृत (var isAuthenticated = ...) जाता है। इसके बाद हम किसी भी सार्वजनिक विधि को हरा देंगे। यह राज्य ऑब्जेक्ट परिभाषा की data {} संपत्ति के साथ किया जाता है (Attach Custom Data to State Objects देखें)

और यही वह है।एक नीचे स्निपेट में तरह परिभाषित राज्यों के मामले में हम अनुभव कर सकते हैं:

  • 'public', 'home''private', 'private' रीडायरेक्ट करेगा लॉगइन करने के लिए किसी को भी
  • की अनुमति दी जाती है, तो isAuthenticated === false
  • 'login' इस उदाहरण में त्वरित तरीका प्रदान करता है कि कैसे पर isAuthenticated स्विच/बंद

    // States 
    $stateProvider 
    
        // public 
        .state('home', { 
         url: "/home", 
         templateUrl: 'tpl.html', 
         data: { isPublic: true }, 
        }) 
        .state('public', { 
         url: "/public", 
         templateUrl: 'tpl.html', 
         data: { isPublic: true }, 
        }) 
        // private 
        .state('private', { 
         url: "/private", 
         templateUrl: 'tpl.html', 
        }) 
        .state('private2', { 
         url: "/private2", 
         templateUrl: 'tpl.html', 
        }) 
    
        // login 
        .state('login', { 
         url: "/login", 
         templateUrl: 'tpl.html', 
         data: { isPublic: true }, 
         controller: 'loginCtrl', 
        }) 
    
को

चेक कि सभी here

कुछ अन्य संसाधनों:

+0

मैं सोच रहा हूं .. हो सकता है कि मार्ग परिवर्तन प्रति बार अधिक ट्रैफ़िक के लिए एक HTTP अनुरोध कर रहा हो, तो उपयोगकर्ता को अनधिकृत होने के लिए यह देखने के लिए विंडोज़ या एक सेवा के उपयोगकर्ता ऑब्जेक्ट भाग को बेहतर ढंग से सेट नहीं किया जाएगा? – rahpuser

+0

यदि मैं आपकी समस्या को सही तरीके से समझता हूं, तो अच्छी खबर ** ** हल हो गई है;) कोणीय 'प्रदाता' मॉडल * ('सेवाएं 'और' कारखानों 'सहित) * ** सिंगलटन ** पैटर्न द्वारा संचालित है। तो हमारे उदाहरण में ** 'userService' ** केवल ** एक बार ** तुरंत चालू हो जाएगा, केवल एक बार सर्वर * (यहां' $ टाइमआउट') कॉल करेगा * और इसके लिए कोई भी अगली कॉल 'उपयोगकर्ता' स्थानीय वापस कर देगी परिवर्तनीय ... क्या यह मदद करता है? –

+0

ओप .. हाँ, माफ करना मुझे getAuthObj और isAuth .. के साथ भ्रमित हो गया – rahpuser

संबंधित मुद्दे