【问题标题】:Angularjs: Making another $http request inside a $http interceptorAngularjs:在 $http 拦截器中发出另一个 $http 请求
【发布时间】:2016-09-19 18:42:33
【问题描述】:

我有一个简单的(半成品)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 标头中传递。

【问题讨论】:

    标签: angularjs angularjs-http


    【解决方案1】:

    您可以检查请求的 url 以防止无限循环。此外,您可以返回一个可以解决的承诺,而不是直接返回配置,这样您就可以等到您有一个有效的令牌。例如

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

    【讨论】:

    • 在拦截器中使用 $http 会导致循环引用错误
    • 对,你要const $http = $injector.get('$http');
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    • 2014-05-26
    • 1970-01-01
    相关资源
    最近更新 更多