Angularjs:在$ http拦截器中创建另一个$ http请求

时间:2016-05-23 01:55:56

标签: angularjs angularjs-http

我有一个简单的(半完成的)http拦截器,它将Bearer令牌(存储在$window.sessionsStorage中)附加到标头,以便可以验证REST API请求:

function accessTokenHttpInterceptor($window, $http) {

  // Try to get token details from sessionStorage
  var accesstoken=$window.sessionStorage.getItem('userInfo-accesstoken');
  var refreshtoken=$window.sessionStorage.getItem('userInfo-refreshtoken');
  var tokenexpiry=$window.sessionStorage.getItem('userInfo-tokenexpiry');

  return {

    request: function($config) {

      // Check if the access token, refresh token and expiry date exists:
      if (accesstoken == undefined || refreshtoken == undefined || tokenexpiry == undefined) {
        console.log('Missing token details');
        // TODO REDIRECT TO LOGIN PAGE
      }

      // We have an access token. Has it expired?
      var expiry = new Date($window.sessionStorage['userInfo-tokenexpiry'])
      var now = new Date
      if (now > expiry ) {
        console.log('Token expired');
        // TODO REFRESH THE TOKEN
        };

      // Set the authorization header
      $config.headers['Authorization'] = 'Bearer ' + accesstoken;
      return $config;

    },
  };
}

accessTokenHttpInterceptor.$inject=['$window'];

function httpInterceptorRegistry($httpProvider) {
    $httpProvider.interceptors.push('accessTokenHttpInterceptor');
}

angular
    .module('myApp')
    .config(httpInterceptorRegistry)
    .factory('accessTokenHttpInterceptor', accessTokenHttpInterceptor)

如您所见,我可以在调用API之前查看令牌是否已过期。

在发出实际的API请求之前,有人可以帮我解释如何刷新令牌吗?我认为再次拦截另一个$ http请求会以无限循环结束。 通过向API发出POST请求来刷新令牌,其中刷新令牌作为参数传递,而不像其他API请求那样在Authorization头中传递。

1 个答案:

答案 0 :(得分:1)

您可以检查请求的网址以防止无限循环。此外,您可以返回一个使用它解析的promise,而不是直接返回配置,这样您就可以等到有一个有效的令牌。 e.g。

{
    request: function(config) {
        if(config.url != 'my/refresh/url') {
            var promiseToHaveValidToken;

            var expiry = new Date($window.sessionStorage['userInfo-tokenexpiry']);
            var now = new Date();
            if (now > expiry ) {
                promiseToHaveValidToken = $http.get('my/refresh/url').then(function (response) {
                    return response.data.token;
                });
            } else {
                promiseToHaveValidToken = $q.resolve(sessionStorage['userInfo-accesstoken']);
            }

            return promiseToHaveValidToken.then(function (token) {
                config.headers['Authorization'] = 'Bearer ' + token;
                return config;
            });
        }
    }
}