Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Varnish缓存RESTful API,但仍然使用HMAC对每个请求进行签名/验证?_Api_Rest_Caching_Varnish_Hmac - Fatal编程技术网

如何使用Varnish缓存RESTful API,但仍然使用HMAC对每个请求进行签名/验证?

如何使用Varnish缓存RESTful API,但仍然使用HMAC对每个请求进行签名/验证?,api,rest,caching,varnish,hmac,Api,Rest,Caching,Varnish,Hmac,我对使用Varnish来缓存/限制/etc对我正在创建的RESTful API的响应感兴趣。我可能使用术语/首字母缩略词“HMAC”太过松散,但我的意思是,对我的API的每个请求都应该包含一个头,该头包含一个哈希值,该哈希值是客户端通过使用共享秘密对请求的部分(包括时间戳)进行哈希计算得到的。然后,服务器使用请求中的相同成分计算相同的散列,并确定请求是否有效以及是否应该响应 这已经足够好了,但是现在我想使用Varnish来缓存我的API响应。HMAC的本质要求每个请求计算散列以验证用户是谁,但返

我对使用Varnish来缓存/限制/etc对我正在创建的RESTful API的响应感兴趣。我可能使用术语/首字母缩略词“HMAC”太过松散,但我的意思是,对我的API的每个请求都应该包含一个头,该头包含一个哈希值,该哈希值是客户端通过使用共享秘密对请求的部分(包括时间戳)进行哈希计算得到的。然后,服务器使用请求中的相同成分计算相同的散列,并确定请求是否有效以及是否应该响应

这已经足够好了,但是现在我想使用Varnish来缓存我的API响应。HMAC的本质要求每个请求计算散列以验证用户是谁,但返回的实际响应是相同的,因此API调用的内容非常可缓存

我想要的(我假设这可以实现,我只是不知道如何实现)是将身份验证任务传递到后端,以某种方式告诉Varnish“是的,继续并响应此请求”或“否,不响应此请求”,然后让Varnish从那里确定是否可以从缓存服务请求


更理想的做法是做一些稍微花哨的事情,允许Varnish自己处理身份验证,或者将HMAC处理传递到比后端更快的东西上。例如,API可能将客户机密钥/公钥存储在redis缓存中,然后Varnish可能实际使用redis中的值计算哈希本身

您应该能够使用以下两种语言在Varnish代码(Varnish配置语言)中实现fancier解决方案:

  • 去拿钥匙
  • 用于计算/处理HMAC
这两个模块都用于生产,如中所列

如果Varnish在VCL中处理身份验证,则可以让Varnish缓存API后端响应,并仅为经过身份验证的请求提供响应

如果HMAC实施需要请求主体:

与他/她的回答一样,Varnish无法访问请求主体。我们可以/不应该从后端/应用程序发送HTTP头中的完整请求正文

但是,我们可以在HTTP头中发送完整请求体的哈希/摘要。与生成输出(标记|数据|任何内容)相比,后端哈希的计算应该可以忽略不计。
AFAICT只要hash/digest和HMAC是健壮的,并且digest很长(256bit或更多),这种方法就不应该有任何密码学/实际的缺点。性能测试像往常一样得到建议。

Varnish可以使用Geir-Bostad答案中的VMOD轻松完成HMAC,除非您的HMAC实现将请求主体用作哈希的一部分。 Varnish不提供对请求主体的访问,提供了一些函数,但我没有找到实际获取请求主体的方法

理论上,您可以添加一个包含请求主体的头,但这是一种非常糟糕的做法,它会用冗余数据阻塞HTTP请求,或者如果您选择只将数据放在头中,则会破坏HTTP请求标准。简单地说,我们不建议这样做

另一种解决方案是使用Nginx,如果您想使用HTTPS(Varnish不做SSL),Nginx还可以充当SSL终止符。 Nginx有一个运行Lua脚本的工具(Ubuntu/Debian软件包Nginx extras提供了它,而不需要您自己编译),该模块提供了方便的指令,允许或阻止基于脚本结果的访问。
Nginx有一个HMAC脚本。

您可以将身份验证任务传递给后端,在内部将请求一分为二,或者使用内联C实现HMAC inside Varnish。感谢您的回复@NITEMAN-我是Varnish新手,从性能/可伸缩性的角度来看,这看起来像是“OK”吗?我提到使用Redis之类的工具在应用程序和varnish之间共享密钥/令牌信息,如果我在varnish内部实现HMAC,这看起来是一个好方法吗?再次感谢!我很难说(没有在大型系统中内联重要的C代码的经验),但理论上它应该可以很好地工作和扩展。如果你关心性能,也许写一个清漆模块是最好的选择。谢谢@NITEMAN。老实说,我不太确定写这样一个清漆模块会涉及到什么,但我要调查一下。@KevinMitchell:这对你来说是怎么回事?当然,只有在您能够(例如,您的雇主允许)以及其他此类考虑因素允许的情况下,您才会非常感激任何经验;)我要检查这两个。非常感谢。对于“如果HMAC实现将请求主体用作散列的一部分”,我可以想出一个可能的解决方案:让应用程序计算主体的散列,并在http头(而不是整个主体)中返回散列。我不知道这种方法是否有任何重大的密码学/实际缺点。选择一个较长的散列(可能是256位或更多)应该可以。长哈希可能有性能问题,因此需要进行测试和基准测试。