Angular HTTP拦截器中的HTTP请求

3
我需要将必要的HMAC头附加到请求中。这应该不是很难,但我开始感到沮丧。以下代码有什么问题?我自己运行了实际的http调用,并返回了必要的数据,但在拦截器内它不起作用。
在我添加白名单或黑名单和其他可自定义数据之前,我只想让当前实现工作。这不是关于hmac的问题,而是关于promise的问题。
这个拦截器中的错误在于整个promise行,从$http(...)开始。当我删除此块并像原样使用它(减去promise执行)时,它可以正常工作。一旦我取消注释该行,它就会陷入循环并崩溃Chrome。我已经阅读过的所有地方都说这就是做法,但这显然不起作用。
function requestInterceptor(config){
  var $http = $injector.get('$http');
  var deferred = $q.defer();

  $http.get(hmacApiEndpoint, {cache: true}).then(function(data){
    console.log('HMAC - Success', data)
    deferred.resolve(config)
  }, function(config){
    console.log('HMAC - Error', config)
    deferred.resolve(config)
  })

  return deferred.promise;
}

return {
  request: requestInterceptor
};

这是否与Angular的$http承诺与'$q'的实现不同有关?


1
那个来自请求requestInterceptor$http调用会再次调用requestInterceptor吗?我怀疑它会递归调用。 - Pankaj Parkar
1
@pankajparkar,我几乎可以确定它会……所以,为了避免无限循环,您应该仅将拦截器应用于除hmacApiEndpoint之外的URL。而$http返回相同的承诺+额外的.success/.error-因此,它是相同的或兼容的。 - New Dev
1个回答

6

看起来你没有实际修改 config 以使用新获得的 HMAC。

此外,你需要防止 requestInterceptor 拦截获取 HMAC 的调用,从而导致无限循环。

最后,这里不需要使用 deferred - 只需返回由 $http(或 $http.then())产生的 promise:

function requestInterceptor(config){
  var $http = $injector.get('$http');

  // just return, if this is a call to get HMAC
  if (config.url === hmacApiEndpoint) return config;

  return $http.get(hmacApiEndpoint, {cache: true})
    .then(function(response){
      console.log('HMAC - Success', response.data)

      // not sure where the HMAC needs to go
      config.headers.Authorization = response.data;
      return config;
    })
    .catch(function(){
       return $q.reject("failed to obtain HMAC");
    });
}

return {
  request: requestInterceptor
};

1
好的解决方案,但您能否解释一下如何在进行HMAC的$http.get时不调用拦截器? - Pankaj Parkar
1
@pankajparkar,它会被调用,但它将跳过内部的$http调用(再次)获取HMAC。 - New Dev
2
@pankajparkar,怎么了?{cache: true}设置将使它在没有Ajax请求的情况下检索先前的结果。也许我漏掉了什么? - New Dev
2
那就有意义了..很棒的解决方案..像你一直给出的那样..你太棒了..:) 我给你点赞 - Pankaj Parkar
太棒了!这正是发生的事情。我从这个例子中删除了hmac头,因为它们是任意的。无限循环是我忽略的。你是正确的,http拦截器正在拦截自己的响应,因此永远不会解决。缓存true在非常天真的意义上只允许一次调用,但原始调用被拦截,因此cacheFactory永远不会填充值。感谢您提供的解决方案,您所说的一切都是完全有道理的,我忽略了那个递归式的循环。 - Abominable-Panda
同时,让我在这里说明一下,https 应该有一个协议检查。 Hmac 仅在公钥基础设施中是安全的,因此在此情况下(因为 hmac 使用对称密钥加密),密钥的传输需要在安全通道中完成。我可以在此处开头添加类似的检查。 - Abominable-Panda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接