wuj*_*jek 7 python python-requests
我使用Python3.5.1和Requests2.9.1.我的用例如下:我需要从服务T验证(获取令牌)并Authorization在向资源服务器R发出请求时将其用作标头的值.令牌在某个时刻到期并且需要获取新的令牌.
我有一个使用的应用程序requests,在启动时首先获取一个令牌并记住它 - 设置Session用于对R的请求.从那时起3分钟,一切都作为一个魅力.3分钟后,我得到unauthorized回复,因为令牌无效.
我Session用于所有请求,除了要进行身份验证的请求; 此调用更新了要使用的其他请求的Authorization标头Session.
我创建了代码,以便在unauthorized检测到时自动重新进行身份验证,使用response钩子(仅在上面设置Session),这里是代码:
def __hook(self, res, *args, **kwargs):
if res.status_code == requests.codes.unauthorized:
print('Token expired, refreshing')
self.auth() # sets the token on self.__session
req = res.request
print('Resending request', req.method, req.url, req.headers)
req.headers['Authorization'] = self.__session.headers['Authorization'] # why is it needed?
return self.__session.send(res.request)
Run Code Online (Sandbox Code Playgroud)
基本上,它甚至可以工作.但是有几个问题:
为什么有必要Authorization在请求上重新设置标头,即使会话已更新并用于重新发送原始请求?如果没有该行,应用程序将继续刷新令牌,因为新的令牌从未使用过,这可以在输出中看到,令牌是导致自动刷新的原始令牌.
如何使代码更加健壮,即防止无休止的递归(我不确定它是否可能在现实中,但是Authorization在重试的请求中设置标题的行将继续进行)?我正在考虑设置一个自定义标头,如果挂钩发现失败的请求有它,它将不会重新进行身份验证和重新发送.有更好的吗?
编辑:事实证明,如果配置错误,可能会得到(几乎)无限循环(毕竟它是递归的):令牌用于一个环境(如STAGING),但资源服务器来自另一个( TEST) - auth请求将成功,但令牌实际上对资源服务器不正确.目前我实现了上面提到的"特殊"头部解决方案.
这是一般的好方法还是有更适合任务的东西requests?
Yes*_*esh 12
这是相同的解决方案,但不使用类
session = requests.Session()
session.headers.update({"Authorization": f"Bearer deliberate-wrong-token"})
def refresh_token(r, *args, **kwargs):
if r.status_code == 401:
logger.info("Fetching new token as the previous token expired")
token = get_token()
session.headers.update({"Authorization": f"Bearer {token}"})
r.request.headers["Authorization"] = session.headers["Authorization"]
return session.send(r.request, verify=False)
session.hooks['response'].append(refresh_token)
Run Code Online (Sandbox Code Playgroud)
所以我联系了请求作者讨论一个不相关的问题并询问了这个问题,事实证明这种方法是好的。我所做的唯一更改是删除自定义标头(它确实有效并且也可以),现在我只需在重新发送请求之前取消注册挂钩内的响应挂钩。这打破了循环,一切都很好。