2017-03-22 7 views
1

Ich versuche zu verstehen, wie in Ansible 1.5.3 ein httpInterceptor zu schreiben.Angular - HttpInterceptor + Async Anruf

auf http://www.webdeveasy.com/interceptors-in-angularjs-and-useful-examples/

(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'); 
} 

Jetzt Basierend Ich verstehe nicht, wie MyService zu schreiben (es führt eine GET).

Ich habe versucht, in myconfig Funktion hinzuzufügen, aber ich bin in zirkulärer Abhängigkeit verloren:

$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; 
    }) 

Kann mir jemand helfen?

Riccardo

Antwort

0

Teilen Sie einfach meine Arbeitslösung. Vielleicht kann ein NodeJS Guru dies bestätigen.

Riccardo

(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'); 
}