3

我正在使用 http Interceptor 来拦截我的应用程序中的每个 http 请求。但我发现循环依赖:$http <- APIInterceptor <- $http <- $templateRequest <- $compile

这是我的服务代码:

mPosServices.factory('mosServiceFactory', function ($http, $rootScope, $cookies, $q) {
    return{
         refresh_token: function () {
            var refreshToken = $http({
                method: "get",
                url: "myservice/oauth/token?grant_type=refresh_token&client_id=restapp&client_secret=restapp&refresh_token=" + $cookies.get('refresh_token'),
            })
            return refreshToken;
        }
});

mPosServices.service('APIInterceptor', ['mosServiceFactory','$cookies',function (mosServiceFactory,$cookies) {
        var service = this;
        service.request = function (config) {
            if (!$cookies.get('access_token')) { //if access_token cookie does not exist
               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);
                }); //call the refresh_token function first
            }
            return config;
        };

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

并将其推为:

$httpProvider.interceptors.push('APIInterceptor');

在配置函数中。我在这里做错了吗?即使我尝试使用手动注入 $http

$注射器

,但得到同样的错误。请帮助我。

4

1 回答 1

4

您确实需要添加使用$injector来获取mosServiceFactory拦截器内部的实例。但这并不是您需要做的全部。您还需要确保您不会陷入无限请求循环,因为拦截器也会发出请求。您可以做的是检查当前请求是否是令牌刷新的请求,如果是,请不要再触发一个请求,我正在检查 URL。

还有一件更重要的事情要提。您需要从解析为原始请求的拦截器返回承诺对象config。这样就保证了截获的请求在获取令牌后会被重新发出。

所有这些看起来像这样:

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

查看我正在测试解决方案的演示,了解它在加载令牌后如何恢复原始请求。

演示: http ://plnkr.co/edit/1Aey2PThZQ4Y8IRZuVOl?p=preview

于 2015-06-26T06:54:07.987 回答