我正在尝试运行一个python脚本,该脚本在一定时间间隔内调用一个外部API(我只能对其进行读取),该API使用基于cookie的身份验证:调用/auth
端点最初会设置会话cookie,然后将其用于在其他请求中进行身份验证。
关于我的问题:因为身份验证基于活动会话,所以一旦连接断开,cookie无效,因此必须重新启动。从我阅读的内容来看,requests
它基于urllib3
,默认情况下可使连接保持活动状态。但是,经过几次测试,我注意到在某些情况下,连接还是会断开。
我使用了模块中的Session
对象,requests
并测试了断开连接所需的时间,如下所示:
from requests import session
import logging
import time import time, sleep
logging.basicConfig(level=logging.DEBUG)
def tt(interval):
credentials = {"username":"user","password":"pass"}
s = Session()
r = s.post("https://<host>:<port>/auth", json=credentials)
ts = time()
while r.status_code is 200:
r = s.get("https://<host>:<port>/some/other/endpoint")
sleep(interval)
return time() - ts # Seconds until connection drop
可能不是找出答案的最佳方法,但是我让该函数运行两次,一次间隔1秒,然后间隔1分钟。两者都运行了大约一个小时,直到我不得不手动停止执行为止。
但是,当我在while
循环中交换两行时,这意味着在初始POST /auth
请求之后有1分钟的延迟,以下GET
请求失败并显示,401 Unauthorized
并且此消息已预先记录:
DEBUG:urllib3.connectionpool:Resetting dropped connection: <host>
由于在prod脚本中请求的时间间隔可能从几分钟到几个小时不等,因此我必须事先知道这些会话的有效期以及该规则是否存在某些例外情况(例如,如果在首字母POST /auth
缩写是短暂的)。
那么,连接可以保持多长时间,requests
或者urllib3
是否可以无限期延长该时间?
还是服务器而不是requests
断开连接?
通过使用requests.Session
,自动为您处理保持活动。
在进行/auth
呼叫后连续轮询服务器的循环的第一个版本中,由于后续GET
发生的情况,服务器不会断开连接。在第二个版本中,休眠间隔很可能超过了服务器配置为保持连接打开的时间。
取决于API的服务器配置,响应标头可能包括Keep-Alive
标头,其中包含有关连接保持最少打开时间的信息。HTTP/1.0
指定此信息包含在标头的timeout
参数中Keep-Alive
。您可以使用此信息来确定服务器断开连接之前需要等待多长时间。
在中HTTP/1.1
,默认情况下使用持久连接,Keep-Alive
除非服务器为向后兼容而显式实现它,否则不使用标头。由于这种差异,客户端无法立即确定连接的确切超时,因为它可能仅作为服务器端配置存在。
保持连接打开的关键是定期进行轮询。您使用的间隔必须小于服务器配置的连接超时。
要指出的另一件事是,以这种方式人为地无限期地延长会话长度,会使会话固定攻击更加脆弱。您可能需要考虑添加偶尔会重新建立会话的逻辑,以最大程度地减少此类攻击的风险。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句