2015-08-05 1 views
0

Je construis mon (premier) application angulaire qui ont des jetons insérés dans les en-têtes (le contenu affiché est pour la plupart provenant here)

angular.module (« myApp »)

.factory('sessionInjector', ['SessionService', function(SessionService) { 
    var sessionInjector = { 
     request: function(config) { 
      config.headers['x-session-token'] = SessionService.getToken(); 
      return config; 
     } 
    }; 
    return sessionInjector; 
}]) 

.config(['$httpProvider', function($httpProvider) { 
    $httpProvider.interceptors.push('sessionInjector'); 
}]) 

le problème que je vais avoir est avec SessionService - comment puis-je initialiser ce avec l'appel au serveur?

Par exemple, cela ne fonctionne pas:

.factory('SessionService', ['$injector', function($injector){ 
    var token = ""; 

    return { 
     getToken: function() { 
      var http = $injector.get('$http'); 
      if (token === "") { 
       http.get('http://localhost/api/auth/getToken').success(function (ret) { 
        token = ret; 
       }); 
      } 
      return token; 
      //I can see a $q/deferred/promise should be used somehow here... 
      //but I'm not sure it solves the problem I'm having... 
     } 
    } 
}]); 

parce qu'il vient surchargent mon cpu à 100% ...

Comme il est ma première application angulaire, je suis sûr que je suis Il manque quelque chose, mais ... quoi?

EDIT:
une autre prise sur la question ... ne fonctionne toujours pas si ... (encore une fois, utilise jusqu'à cpu, boucle probablement infinie)

.factory('sessionData', function() { 
    var currentToken = '[uninitialized-token]'; 

    return { 
     getToken: function() { 
      return currentToken; 
     }, 
     setToken: function (token) { 
      currentToken = token; 
     } 
    } 
}) 

.factory('sessionInjector', ['sessionData', '$injector', '$q', function (sessionData, $injector, $q) { 
    var sessionInjector = { 
     request: function (config) { 
      var deferred = $q.defer(); 
      var http = $injector.get('$http'); 
      http.get('http://localhost/api/auth/getToken').success(function (ret) { 
       sessionData.setToken(ret); 
       console.log("successfully authenticated with token " + sessionData.getToken()); 
       config.headers['x-header-sessionID'] = sessionData.getToken(); 
       deferred.resolve(config); 
      }) 
      .error(function(){ 
       console.log("failed to authenticate"); 
       deferred.resolve(config); 
      }); 

      return deferred.promise; 
     } 
    }; 
    return sessionInjector; 
}]) 

.config(['$httpProvider', function ($httpProvider) { 
    $httpProvider.interceptors.push('sessionInjector'); 
}]) 

.run(['$http', 'sessionData', function ($http, configs, sessionData) { 
    $http.get('http://localhost/api/auth/testMethod').then(function (ret) { 
     //do something... 
    }); 
}]) 

Répondre

0

réponse était en fait assez simple - si l'URL est ciblée pour la connexion, alors n'injectent rien (chercher le commentaire the fix):

.factory('sessionData', function() { 
    var currentToken = '[uninitialized-token]'; 

    return { 
     getToken: function() { 
      return currentToken; 
     }, 
     setToken: function (token) { 
      currentToken = token; 
     } 
    } 
}) 

.factory('sessionInjector', ['sessionData', '$injector', '$q', function (sessionData, $injector, $q) { 
    var sessionInjector = { 
     request: function (config) { 

      //The fix: 
      if(config.url === 'http://localhost/api/auth/getToken') 
       return config; 

      var deferred = $q.defer(); 
      var http = $injector.get('$http'); 
      http.get('http://localhost/api/auth/getToken').success(function (ret) { 
       sessionData.setToken(ret); 
       console.log("successfully authenticated with token " + sessionData.getToken()); 
       config.headers['x-header-sessionID'] = sessionData.getToken(); 
       deferred.resolve(config); 
      }) 
      .error(function(){ 
       console.log("failed to authenticate"); 
       deferred.resolve(config); 
      }); 

      return deferred.promise; 
     } 
    }; 
    return sessionInjector; 
}]) 

.config(['$httpProvider', function ($httpProvider) { 
    $httpProvider.interceptors.push('sessionInjector'); 
}]) 

.run(['$http', 'sessionData', function ($http, configs, sessionData) { 
    $http.get('http://localhost/api/auth/testMethod').then(function (ret) { 
     //do something... 
    }); 
}]) 
1

Vérifiez si ce code modifié fragment résoudra vos problèmes.

.factory('SessionService', ['$http', '$q', function($http, $q) { 
    var token = null; 
    var sessionService = {}; 
    var differred = $q.defer(); 

    sessionService.readToken = function() { 
     return $http.get('http://localhost/api/auth/getToken') 
      .success(function (res) { 
       console.log('Auth Success and token received: ' + JSON.stringify(res.data)); 

       // Extract the token details from the received JSON object 
       token = res.data; 
       differred.resolve(res); 
      }, function (res) { 
       console.log('Error occurred : ' + JSON.stringify(res)); 
       differred.reject(res); 
      } 
     ) 
    }; 

    sessionService.getToken = function() { 
     return token; 
    }; 

    sessionService.isAnonymous = function() { 
     if (token) 
      return true; 
     else 
      return false; 
    }; 

    return sessionService; 
}]) 


.factory('sessionInjector', ['SessionService', function(SessionService) { 
    var sessionInjector = { 
     request: function(config) { 
      if (!sessionService.isAnonymous) { 
       config.headers['x-session-token'] = SessionService.getToken(); 
       return config; 
      } 
     } 
    }; 
    return sessionInjector; 
}]) 

.config(['$httpProvider', function($httpProvider) { 
    $httpProvider.interceptors.push('sessionInjector'); 
}]) 
+0

Merci pour la réponse - mais ne fonctionne pas. Le $ http que vous utilisez n'est pas injecté. Et même si c'était le cas, cela créerait une référence circulaire et ne fonctionnerait pas. C'est pourquoi j'ai dû obtenir le $ http de $ injector au moment de la demande de jeton (à l'intérieur d'une fonction, sous son contexte à l'exécution) – veljkoz

+0

Il y avait une faute de frappe dans la déclaration du service de session qui corrigeait. De plus, vous devez d'abord appeler la méthode 'Session.readToken()' dans votre contrôleur pour le lire. Ensuite, si un jeton est disponible, toutes les demandes consécutives seront envoyées avec le jeton en tant que paramètre d'en-tête HTTP. Cela fonctionne et testé. Aucune référence circulaire n'a été observée, comme je l'ai définie. – Aviro

+0

Voici l'erreur circulaire que j'obtiens lorsque j'utilise votre code: 'Erreur non détectée: [$ injector: cdep] Dépendance circulaire trouvée: $ http <- SessionService <- sessionInjector <- $ http <- $ templateRequest <- $ compile '(AngularJS v1.4.3) – veljkoz