2015-06-25 24 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