2015-06-25 23 views
1

我正在使用角度項目。當我登錄到應用程序時,我將從登錄服務收到的access_token保存到$ cookie中。此access_token將在2分鐘後過期。 登錄後,爲了獲得最後的功能,我必須使用$ http將此access_token發送到服務以獲取有效響應。 一旦此access_token在2分鐘後過期,我正在呼叫一個服務,該服務將重新生成access_token並再次保存$ cookie。 沒有access_token,我的其他功能將不起作用。在Angular js中調用其他ajax調用

基本上我需要檢查訪問令牌是否存在於$ cookie中,或者不在應用程序中的每個服務調用之前。如果訪問令牌不存在,那麼需要使用$ http使用另一個服務調用重新生成它,然後將其保存回cookie中,然後將其保存到功能的期望服務調用中。並且如果存在令牌,則進行期望的服務呼叫。

我的功能之一是:

mPosController.controller('offerController', ['$scope', '$route', '$cookies', '$rootScope', 'mosServiceFactory', 'ngDialog', '$modal', '$q', function ($scope, $route, $cookies, $rootScope, mosServiceFactory, ngDialog, $modal, $q) { 

     mosServiceFactory.viewAllOffers('page=0').then(function (data) { 
       //Do the desire functionality 
      }); 
    }]); 

我的服務宗旨是:

mPosServices.factory('mosServiceFactory', function ($http, $rootScope, $cookies,$q) { 
    return{ 
     viewAllOffers: function (page) { 
      var allOffers = $http({ 
       method: "get", 
       url: "myserviceurl?enrollmentId=" + $rootScope.enrollMentId + "&" + page + "&size=10&access_token=" + $cookies.get('access_token'), 
      }); 
      return allOffers; 
     }, 
     refresh_token: function() { 
      var refreshToken = $http({ 
       method: "get", 
       url: "myserviceurl/oauth/token?grant_type=refresh_token&client_id=restapp&client_secret=restapp&refresh_token=" + $cookies.get('refresh_token'), 
      }) 
      return refreshToken; 
     }, 
} 
}); 

所以調用viewAllOffers(),我需要檢查的access_token存在於$ cookie或沒有,如果不是之前然後調用refresh_token服務。

我該如何做到這一點?

+0

您可以嘗試使用'http http'服務中的'request'攔截器,[here](https://docs.angularjs。org/api/ng/service/$ http)是一些文檔,向下滾動到**攔截器**部分 – MiTa

回答

2

基本上我需要檢查在應用程序中每個服務調用之前訪問令牌是否存在於$ cookie中或不存在 。如果訪問令牌不是 ,那麼需要重新生成它。

..我如何實現這一般性?

您可以簡單地創建一個interceptor,以檢查是否存在於餅乾access_token使任何$http調用之前。您需要添加使用$injector才能在攔截器內獲得mosServiceFactory實例。

mPosServices.service('APIInterceptor', ['$injector', '$cookies', function($injector, $cookies) { 
    var service = this; 
    service.request = function(config) { 
     if (!$cookies.get('access_token') && config.url.indexOf('myservice/oauth/token?grant_type=') === -1) { 
      return $injector.get('mosServiceFactory').refresh_token().then(function(response) { 
       var date = new Date(); 
       date.setTime(date.getTime() + (response.data.expiresIn * 1000)); 
       $cookies.remove('access_token'); 
       $cookies.put('access_token', response.data.value, { 
        expires: date 
       }); 
       $cookies.put('refresh_token', response.data.refreshToken.value); 
      }).then(function() { 
       return config; // <-- token is refreshed, reissue original request 
      }); 
     } 
     return config; 
    }; 

    service.responseError = function(response) { 
     return response; 
    }; 
}]); 

APIInterceptor將監視與$http服務發出的所有請求,則執行的先決條件的操作(像的access_token再生)和攔截任何響應的錯誤。

您需要在您的config函數中將攔截器推送到$httpProvider

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

編輯:由於請求refresh_token還利用$http服務的,​​你會得到一個循環依賴錯誤。這是因爲每次你找到空的時候,攔截器都會嘗試從mosServiceFactory.refresh_token()中得到一個新的令牌,這個令牌會再次發揮攔截器的作用。爲了避免這種情況,您需要在APIInterceptor之內進行檢查,以便讓請求繼續進行如果grant_type !='refresh_token'

+0

我正在做與上面代碼中顯示的完全相同的東西,但我得到的錯誤爲 **「Circular dependency發現:$ http < - mosServiceFactory < - APIInterceptor < - $ http < - $ templateRequest < - $ compile「** 不知道我在做什麼錯在這裏。 – Rahul

+0

@Rahul:是的,我錯過了它。你得到了循環依賴錯誤,因爲APIInterceptor每當它找不到access_token時就調用mosServiceFactory.refresh_token。因爲Interceptors在所有請求/響應週期中都充當中間件,所以即使$ http請求是由refresh_token本身創建的,它也會嘗試調用'refresh_token'。請檢查更新後的答案。 – nalinc

+0

ohh yes..now我明白爲什麼我得到這個錯誤,但配置對象有grand_type屬性?或者我們需要爲每個$ http調用設置此屬性,以便它可以在攔截器中捕獲? – Rahul