2016-05-07 63 views
4

我正在使用Python 3.5.1与Requests 2.9.1。我的用例如下:我需要从服务T进行身份验证(获得令牌),并在向资源服务器R发出请求时将其用作Authorization头的值。令牌在某个时间点到期并需要获取新令牌。Python请求 - 重新验证后的重试请求

我有一个使用requests的应用程序,它在启动时首先获取一个令牌并记住它 - 设置用于请求R的Session。从此开始3分钟,所有事情都起到魅力的作用。 3分钟后,由于令牌无效,我收到unauthorized响应。

我使用Session所有请求除了为一个验证;此调用会更新Session上的Authorization标头以供其他请求使用。

我创建的代码来当检测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) 

基本上,它甚至工程。有一对夫妇的问题,但:

  1. 为什么有必要重新设置上的要求Authorization头,即使会话被更新,并用于发送原始请求吗?没有这条线,应用程序将继续刷新令牌,因为从未使用新令牌,这可以在输出中看到,令牌是导致自动刷新的原始令牌。

  2. 我该如何使代码更健壮,即防止无尽的递归(我不确定它是否可能在现实中,但通过在重试请求上设置Authorization标题,它只会继续) ?我正在考虑设置一个自定义标题,如果挂钩发现失败的请求,它将不会重新进行身份验证并重新发送。有更好的吗? 编辑:事实证明,如果配置错误,则可能会得到一个(几乎)无限循环(毕竟它是递归的):令牌是针对一个环境(如STAGING)采用的,但资源服务器是从另一个(TEST) - auth请求将成功,但对于资源服务器,令牌实际上不正确。目前我实施了上述的'特殊'头部解决方案。

这是一个很好的做法,一般的或有什么更好的适用于requests任务?

+0

如果不重置授权头,客户端将不会有新的令牌,并且没有新的令牌,它将在接下来的三分钟后无法发出请求。 – formatkaka

回答

0

因此,我与Requests作者讨论了一个不相关的问题,并询问了这个问题,结果证明这种方法没问题。我做的唯一改变是放弃自定义头(它工作,也是好的),现在我只是在重新发送请求之前注销钩子中的响应钩子。这打破了循环,一切都很好。