2017-07-28 13 views
6

मैं वर्तमान में एक अनुरोध है कि मेरे एपीआई से एक 401 देता है rethrow के लिए निम्न कोड का उपयोग कर रहा कोणीय responseError इंटरसेप्टर में कई प्रतिक्रियाओं को संभालने के लिए:कैसे

responseError: function(rejection) { 
       var authData = localStorageService.get('authorizationData'); 
       if (rejection.status === 401 && authData) { 
        var authService = $injector.get('authService'); 
        var $http = $injector.get('$http'); 
        ̶v̶a̶r̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶ ̶=̶ ̶$̶q̶.̶d̶e̶f̶e̶r̶(̶)̶;̶ 

        var promise = authService.refreshToken(); 

        return ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶ promise.then(function() { 
         return $http(rejection.config); 
        }); 
       } 
       return $q.reject(rejection); 
      } 

यह 1 अनुरोध के लिए अच्छा काम करता है, लेकिन यह 'नहीं करता है टी काम करता प्रतीत होता है अगर मुझे एक पृष्ठ से दो 401 वापस मिलते हैं, जैसे कि जब पृष्ठ अलग-अलग वर्गों को पॉप्युलेट करने के लिए दो एपीआई कॉल के साथ लोड हो रहा है। मैं एकाधिक अवरुद्ध कॉल को पुनर्स्थापित करने के लिए अपना इंटरसेप्टर कैसे प्राप्त कर सकता हूं?

साथ ही, प्रत्येक 401 व्यक्तिगत रूप से इंटरसेप्टर आग नहीं चाहिए? आदर्श नहीं, यह एक पृष्ठ पर एकाधिक रीफ्रेश कॉल का कारण बनता है, लेकिन किसी कॉल के कारण गायब डेटा में सुधार को पुनर्स्थापित नहीं किया जा रहा है।

स्क्रीनशॉट:

responseError: function(rejection) { 
    var authService = $injector.get('authService'); 
    var $http = $injector.get('$http'); 
    var tokenPromise = null; 

    var authData = localStorageService.get('authorizationData'); 
    if (rejection.status === 401 && authData) { 

     if (!tokenPromise) { 
      tokenPromise = authService.refreshToken() 
       .finally(function() { 
       tokenPromise = null; 
      }); 
     }; 

     return tokenPromise.then(function() { 
      return $http(rejection.config); 
     }); 
    } else { 
     throw rejection; 
    } 
} 

ऊपर के उदाहरण अस्वीकृति में:

enter image description here

+2

* चाहिए न कि प्रत्येक 401 के लिए इंटरसेप्टर आग व्यक्तिगत * - यह होना चाहिए। यदि ऐसा नहीं होता है, तो कृपया http://stackoverflow.com/help/mcve प्रदान करें। एक प्लंक/पहेली जो समस्या को दोहराने में सक्षम है, मदद कर सकती है। – estus

+0

आपको दो 401 मिल रहे हैं क्योंकि आप समानांतर में, दो एक्सएचआर स्टेल टोकन के साथ फायरिंग कर रहे हैं। क्या समस्या है जिसके कारण? क्या अंततः एक्सएचआर दोनों के लिए वैध डेटा मिलता है? – georgeawg

+0

@georgeawg मैं जिस व्यवहार को देख रहा हूं वह दो एसिंक अनुरोध है जो पृष्ठ को आग लगने के लिए उपयोग किया जाता है, दोनों 401, दूसरा (?) अनुरोध फिर से चला जाता है और कहता है कि मेरे पास प्रति कॉल का चयन है, पहला चयन खाली है, दूसरा डेटा है – RandomUs1r

उत्तर

1

एक दृष्टिकोण टोकन वादा और श्रृंखला के दूसरे और बाद में पुनः को बचाने के लिए जब तक टोकन ताज़ा पूरा हो गया है है हैंडलर एक टोकन रीफ्रेश वादा बनाते हैं और बाद में टोकन रीफ्रेश होने पर इसे रद्द कर देता है (या तो पूरा या अस्वीकार)। यदि टोकन रीफ्रेश प्रगति पर है, तो एक और अस्वीकृति होती है, जब तक टोकन रीफ्रेश नहीं होता है तब तक जंजीर (और देरी) में पुनः प्रयास करें।

+0

यह वही लगता है जो मुझे चाहिए, हालांकि मैंने कोड के साथ एक अपडेटेड स्क्रीन शॉट पोस्ट किया है, ऐसा लगता है कि यह मेरे पुराने जैसा एक अनुरोध करता है। यह सुनिश्चित नहीं है कि इसे कैसे ठीक किया जाए, लेकिन उपर्युक्त टोकनप्रमोज़ को एकाधिक अनुरोधों के बारे में कैसे पता चलता है? – RandomUs1r

1

काफी समान georgeawg जवाब ...

responseError: function(rejection) { 
       var authData = localStorageService.get('authorizationData'); 
       if (rejection.status === 401 && authData && !isAuthRequest() /* If request for refresh token fails itself do not go into loop, i.e. check by url */) { 
        var authService = $injector.get('authService'); 
        var $http = $injector.get('$http'); 

        var promise = authService.refreshTokenExt(); // look below 

        return ̶promise.then(function() { 
         return $http(rejection.config); 
        }); 
       } 
       return $q.reject(rejection); 
      } 

AuthService:

... 
var refreshAuthPromise; 

service.refreshTokenExt = function() { 
    if (refreshAuthPromise == null) { 
    refreshAuthPromise = authService.refreshToken().catch(function() { 
     // Cant refresh - redirect to login, show error or whatever 
    }).finally(function() { 
     refreshAuthPromise = null; 
    }); 
    } 
    return refreshAuthPromise; 
} 
+0

मैंने आज सुबह यह शॉट दिया, नेटवर्क कैप्चर दुर्भाग्यवश दिखता है। मैं अंगुलर 1.6 में एक इंटरसेप्टर के साथ दो async अनुरोधों के साथ ऐसा करना असंभव है। हालांकि, मैं प्रति पृष्ठ स्तर पर अपने वादों को चेन करके कोई भी एसिंक नहीं कर सकता हूं और फिर यह काम करता है, इसलिए मुझे लगता है कि मैं योजना बी के साथ जा रहा हूं। – RandomUs1r