4

Since i'm using Oauth2 to protect my Api, i need to get a new access token before any http requets if the previous access token has expired.

I didn't used event listener much until now.

Here what i did for now (Please let me know if it is correct) :

ApplicationController.js :

app.controller('ApplicationController', function($rootScope, $scope, $localStorage, AuthService){

    // Listening event apiRequested
    $scope.$on('event:apiRequested', function(e) {

        AuthService.token();
        // Restore the access_token in case it has changed
        access_token = $localStorage.getObject('access_token');

    });

})

UserController.js :

$rootScope.$broadcast('event:apiRequested');

// Get Users around
return $http.post(domain+'/api/users?access_token='+access_token.key, data).then(function(response){
    return response;
});

First thing i'm not sure about ... Does $http is processed if the event already executed entirely?

So since i'm not sure, i'm thinking about adding a callback.

Here the idea :

$rootScope.$broadcast('event:apiRequested', function(response){

    if(response){

        // Get Users around
        return $http.post(domain+'/api/users?access_token='+access_token.key, data).then(function(response){
            return response;
        });

    }

});

Please let me know if it is possible to do that or should i use something else than event listener for that case.

Brieuc
  • 3,994
  • 9
  • 37
  • 70

1 Answers1

4

Why don't you use interceptors that is done to intercept HTTP request ? In your case, you shall add this very specific behaviour into the "request" part.

See an interceptor exemple bellow:

var $myService; // Add a constant that store the service
    $httpProvider.interceptors.push(['$location', '$injector', '$q', function($location, $injector, $q) {
                             return {

                               'request' : function(config){
                                 console.log("intercept request", config.url,config)
                                 // Your token shall be retreive in this part
                                 return config
                               },
                               'response' : function(config){
                                 $myService= $myService|| $injector.get('$myService'); // inject the service manually if constant is undefined
                                 console.log("intercept response", config)
                                 // Your token shall be retreive in this part
                                 return config
                               },
                                 'responseError': function(rejection) {

                                     console.log("responseError intercepted" , rejection);
                                      if (rejection.status === 403) {

                                         return $q.reject(rejection);

                                     } else if (rejection.status === 423) {



                                         return $q.reject(rejection);
                                     }else
                                          return $q.reject(rejection);
                                 }
                             };
                         }]);

Interceptors shall be defined into .config(["$httpProvider", function($httpProvider)

aorfevre
  • 5,034
  • 3
  • 21
  • 51
  • I didn't know about interceptors. thank you, i'll dig into that and give my feed back. – Brieuc Jun 02 '15 at 11:25
  • 1
    sure, I added a complement to define where you shall define interceptors – aorfevre Jun 02 '15 at 11:27
  • That is working perfectly, i read about promises/deferred first since i did't know the concept. https://docs.angularjs.org/api/ng/service/$q . May i ask how would you use a service in it? I tried to register the service in the .config but it can't find my AuthService. – Brieuc Jun 02 '15 at 13:09
  • 1
    I update my code for explantion on how add a service – aorfevre Jun 02 '15 at 13:22
  • Thank you it is indeed finding the service. Since that service also use $http request to get the token from the server. I have a circular dependency. I wonder if wrapping my HTTP requests into a single service, factor or into a provider and use it for all the requests would not be a better solution for that case. (as suggested here, http://stackoverflow.com/questions/20647483/angularjs-injecting-service-into-a-http-interceptor-circular-dependency#answer-24697285 ). – Brieuc Jun 02 '15 at 13:49
  • or i should just check the config.url that way if(!config.url.includes('/oauth/v2/token') && config.url.includes('/api')){ // call service } this seems to work. Let me know what do you think ;). Thank you! – Brieuc Jun 02 '15 at 14:08
  • 1
    can't tell you ;) don't know... You have to try héhé – aorfevre Jun 02 '15 at 14:09