2017-03-22 77 views
1

我想了解如何在Ansible 1.5.3中編寫一個httpInterceptor。基於http://www.webdeveasy.com/interceptors-in-angularjs-and-useful-examples/Angular - HttpInterceptor +異步調用

(function() { 
'use strict'; 

angular 
    .module('app', ['ui.router', 'ngStorage', 'angular-loading-bar', 'angular-jwt'])     
    .config(myconfig) 
    .run(myrun); 

function myconfig($stateProvider, $urlRouterProvider, $provide, $httpProvider) { 
    ... 
    $provide.factory('httpRequestInterceptor', ['$q', 'MyService', function($q, MyService) { 
     return { 
      'request': function(config) { 
       var deferred = $q.defer(); 
       MyService.execService().then(function(mydata) { 
        // Asynchronous operation succeeded, modify config accordingly 
        console.log("Async OK") 
        deferred.resolve(config); 
       }, function() { 
        // Asynchronous operation failed, modify config accordingly 
        console.log("Async KO") 
        deferred.resolve(config); 
       }); 
       return deferred.promise; 
      } 
     }; 
    }]); 
    $httpProvider.interceptors.push('httpRequestInterceptor'); 
} 

現在我不知道怎麼寫的MyService(執行一個GET)。

我試圖在的myconfig功能添加,但我在循環依賴丟失:

$provide.factory('MyService', function($injector) { 
     var MyService = { 
     async: function() { 
      // $http returns a promise, which has a then function, which also returns a promise 
      console.log("CIAO") 
      var $http = $injector.get('$http'); 
      var promise = $http.get('refresh_token.json').then(function (response) { 
      // The then function here is an opportunity to modify the response 
      console.log(response); 
      // The return value gets picked up by the then in the controller. 
      return response.data; 
      }); 
      // Return the promise to the controller 
      return promise; 
     } 
     }; 
     return MyService; 
    }) 

有人能幫助我嗎?

Riccardo

回答

0

只是分享我的工作解決方案。也許一個NodeJS大師可以驗證。

裏卡多

(function() { 
'use strict'; 

angular 
    .module('app', ['ui.router', 'ngStorage', 'angular-loading-bar', 'angular-jwt'])     
    .config(myconfig) 
    .run(myrun); 

function myconfig($stateProvider, $urlRouterProvider, $provide, $httpProvider) { 
    ... 
    // ---------------------------------------------------------------------- 
    // Interceptor HTTP request 
    // ----------------------------------------------------------------------  
    $provide.factory('MyService', function($injector, $localStorage) { 
     var MyService = { 
      async: function() { 
       // $http returns a promise, which has a then function, which also returns a promise 
       //console.log("STO PER FARE UNA CHIAMATA ASINCRONA!!!") 
       var $http = $injector.get('$http'); 
       console.log("REFRESHTOKEN DA INVIARE: " + $localStorage.currentUser.refreshToken) 
       // La POST va fatta con x-www-form-urlencoded al fine di evitare CORS 
       var promise = $http({ 
        method: 'POST', 
        headers: { 
         'Authorization': undefined, 
         'Content-Type': 'application/x-www-form-urlencoded' 
        }, 
        url: "https://xxxxxxxxxx/v1/refreshToken", 
        transformRequest: function(obj) { 
         var str = []; 
         for(var p in obj) 
         str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); 
         return str.join("&"); 
        }, 
        data: { 
         "refreshToken": $localStorage.currentUser.refreshToken 
        } 
       }).then(function(response) { 
        // The then function here is an opportunity to modify the response 
        // console.log(response); 
        // The return value gets picked up by the then in the controller. 
        return response.data; 
       }); 
       // Return the promise to the controller 
       return promise; 
      } 
     }; 
     return MyService; 
    }) 

    $provide.factory('httpRequestInterceptor', ['$q', "MyService", "$localStorage", "jwtHelper", '$injector', function($q, MyService, $localStorage, jwtHelper, $injector) { 
     return { 
      'request': function(config) { 
       if (config.url.indexOf("/v1/refreshToken") >= 0) { 
        /* Se la request e' generata verso l'endpoint di refreshToken 
         allora salta l'interceptor al fine di evitare dipendenze circolari */ 
        console.log("INFO1: SKIP " + config.url); 
        return config; 
       } else if (config.url.indexOf(".html") >= 0) { 
        /* Se e' l'include di una view, salta l'inteceptor */ 
        console.log("INFO2: SKIP " + config.url); 
        return config; 
       } else if (!$localStorage.currentUser || !$localStorage.currentUser.refreshToken) { 
        /* Se non c'e' una sessione aperta oppure la sessione non prevede refresh 
         allora salta l'interceptor */ 
        console.log("INFO3: SKIP nessun token"); 
        return config; 
       } else if ($localStorage.currentUser.refresh_in_corso == true) { 
        /* Se ci sono diverse chiamate Ajax solo la prima viene fermata. 
         Infatti, visto che l'accessToken non e' del tutto scaduto, 
         e' possibile far coesistire per qualche istante il vecchio 
         accessToken con quello nuovo ottenuto dal processo di refresh */ 
        console.log("INFO4: SKIP refresh in corso"); 
        return config;  
       } else { 
        var $http = $injector.get('$http'); 
        var guard_period = 5 * 60 // seconds 
        var current_timestamp = Math.floor(Date.now()/1000); 
        var exp_timestamp_guard = $localStorage.currentUser.exp - guard_period 
        console.log("NEEDREFRESH" + exp_timestamp_guard + " --> " + new Date(exp_timestamp_guard * 1000)) 
        console.log("NOW  " + current_timestamp + " --> " + new Date(current_timestamp * 1000)) 
        if (current_timestamp <= exp_timestamp_guard) { 
         console.log("INFO5: SKIP non in zona critica"); 
         return config;  
        } else { 
         console.log("INFO6: refresh necessario") 
         $localStorage.currentUser.refresh_in_corso = true; 
         /* Si è nella zona prossima allo scadere del token di accesso 
          E' possibile richiedere il refresh */ 
         console.log("Sono in config: " + config.url + " e apro una chiamata async") 
         var deferred = $q.defer(); 
         MyService.async().then(function(mydata) { 
          console.log("Funzione asincrona terminata con successo") 
          // Asynchronous operation succeeded, modify config accordingly         
          try { 
           var plainPayload = jwtHelper.decodeToken(mydata.accessToken); 
           // store useruid and token in local storage to keep user logged in between page refreshes 
           $localStorage.currentUser = { 
            userUid: plainPayload.usr.uid, 
            systemName: plainPayload.usr.sn, 
            exp: plainPayload.exp, 
            accessToken: mydata.accessToken, 
            refreshToken: mydata.refreshToken, 
            user: mydata.user, 
            refresh_in_corso: true 
           };     

           // add jwt token to auth header for all requests made by the $http service 
           $http.defaults.headers.common.Authorization = 'Bearer ' + mydata.accessToken; 

           $localStorage.currentUser.refresh_in_corso = false; 

           console.log("NUOVO HEADER AUTH: " + $http.defaults.headers.common.Authorization) 
          } 
          catch (err) { 
           $localStorage.currentUser.refresh_in_corso = false; 
           console.log("Token errato. Il refresh non sara' possibile: " + err) 
          } 
          deferred.resolve(config); 
         }, function() { 
          // Asynchronous operation failed, modify config accordingly 
          console.log("Async KO") 
          deferred.resolve(config); 
         }); 
         return deferred.promise; 
        } 
       } 
      } 
     }; 
    }]); 
    $httpProvider.interceptors.push('httpRequestInterceptor'); 
}