2015-06-02 26 views
5

मैंने एपीआई के साथ काम कर एक कोणीय जेएस वेबसाइट बनाई है। यह एपीआई प्रमाणीकरण (ओथ) जैसी कुछ विशेषताएं प्रदान करता है।इंटरसेप्टर में अनंत लूप

जब एपीआई 401 त्रुटि देता है, तो इसका मतलब है कि access_token की समयसीमा समाप्त हो गई है और इसे refresh_token के साथ रीफ्रेश करने की आवश्यकता है।

मैंने AngularJS में एक इंटरसेप्टर बनाया है। इसका लक्ष्य यह जांचना है कि एपीआई द्वारा दिया गया परिणाम 401 त्रुटि है और यदि यह मामला है, तो उसे टोकन रीफ्रेश करना होगा और फिर, पिछले अस्वीकृत अनुरोध को संसाधित करना होगा।

समस्या यह है कि इंटरसेप्टर एक अनंत लूप बनाता है। प्रारंभिक अनुरोध की दूसरी विफलता के बाद, इसे रोकना चाहिए लेकिन ऐसा नहीं है।

angular.module('myApp') 
.factory('authInterceptor', function ($rootScope, $q, $window, $injector) { 

    return { 

    // If the API returns an error 
    'responseError' : function(rejection) { 

     // If it's a 401 
     if (rejection.status == 401) { 

     var deferred = $q.defer(); 

     $injector.get('$http').post('http://my-api.local/api/oauth/token', { 
      grant_type : 'refresh_token', 
      client_id  : 'id', 
      client_secret : 'secret', 
      refresh_token : $window.sessionStorage.refresh_token 
     }, { 
      headers : { 
      'Content-Type' : 'application/x-www-form-urlencoded' 
      }, 
      transformRequest : function(obj) { 
      var str = []; 
      for(var p in obj) 
      str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); 
      return str.join("&"); 
      } 
     }) 
     // New token request successfull 
     .success(function(refreshResponse) { 

      // Processing the failed request again (should fail again because I didn't saved the new tokens) 
      $injector.get('$http')(rejection.config).success(function(data) { 

      deferred.resolve(data); 

      }) 
      .error(function(error, status) { 

      deferred.reject(); 

      }); 

      return deferred.promise(); 

     }) 
     // New token request failure 
     .error(function(error, status) { 

      deferred.reject(); 
      // $location.path('users/login'); 

      return; 

     }); 

     } 
     // If it's another errorenter code here 
     else 
     return rejection; 

    } 

    } 

}); 

तो यह कोड:

  • शुरू होता है जब पहली अनुरोध विफल रहता है
  • अनुरोध ताज़ा टोकन
  • पुनर्प्रयास लेकिन फिर से विफल रहता है (< - मैं सिर्फ यह यहाँ रोक बनाना चाहते)
  • टोकन को रीफ्रेश करता है
  • अनुरोध को पुनः प्रयास करता है लेकिन फिर से विफल रहता है
  • अनुरोध ताज़ा टोकन
  • पुनर्प्रयास लेकिन फिर से विफल रहता है
  • आदि ...
+0

यह सही नहीं दिख रहा है: 'वापसी deferred.promise(); '। आपको केवल वादे ऑब्जेक्ट 'वापसी deferred.promise' वापस करना चाहिए और इसे निष्पादित करने की कोशिश नहीं करनी चाहिए। – user2943490

उत्तर

5

मैं अपने अनुप्रयोग में इस पर काम किया। आपके रीफ्रेश अनुरोध में skipIntercept: true जैसे कॉन्फ़िगर/हेडर वैरिएबल को शामिल करने की आवश्यकता है। फिर जब आप इसे असफल प्रतिक्रिया के रूप में रोकते हैं, तो आप rejection.config.skipIntercept चर देख सकते हैं। यदि यह सत्य है, तो आप सीधे $q.reject(rejection) पर जाएं।

आप कहाँ है: यह करने के लिए

if (rejection.status == 401) { 

बदलें:

if (rejection.status == 401 && !rejection.config.skipIntercept) { 

और फिर इस से ऊपर:

 headers : { 
     'Content-Type' : 'application/x-www-form-urlencoded' 
    }, 

आप जोड़ने की जरूरत:

 skipIntercept: true, 

    headers: { 
     'Content-Type' : 'application/x-www-form-urlencoded' 
    }, 

पीएस। there's an existing solution आप उपयोग कर सकते हैं।

+0

आपका समाधान काम करता है, मेरे पास अनंत लूप नहीं हैं! अपने "मौजूदा समाधान" के बारे में, यह बहुत अच्छा लग रहा है लेकिन यह सभी ताज़ा टोकन सामानों के लिए उपयुक्त नहीं है, है ना? क्या मेरी जरूरतों को अनुकूलित करने का कोई तरीका है? मैं कोणीय के लिए नया हूं और मैं थोड़ा खो गया हूं ... – Flobesst

+0

@ फ्लोब्स्ट गिट रेपो पर रीडेमे फ़ाइल पर एक नज़र डालें, यह बताता है कि इंटरसेप्टर का उपयोग कैसे करें। असल में, रिसेश अनुरोध को छोड़कर, इंटरसेप्टर सब कुछ करता है। इंटरसेप्टर 401 पर फेंकने की स्थिति के लिए आपको केवल एक ईवेंट श्रोता ('$ rootScope। $ (...) पर सेट अप करने की आवश्यकता है, और फिर अपने रीफ्रेश अनुरोध को आग लगाना, और फिर वहां से आगे बढ़ें। – ngDeveloper

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