2017-03-22 69 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'); 
}