token失效后再次请求获取新token

来源:互联网 发布:linux如何安装vsftpd 编辑:程序博客网 时间:2024/05/19 18:40

在neutron日志中发现经常有认证失败warning,但是认证失败并不会导致服务请求报错,这是什么原因呢?

在keystonemiddleware中打印认证的token,发现认证失败的token都是已经过期的token,这些过期的token认证时肯定是失败的,所以返回认证失败。在认证失败后,服务会再次请求获取新的token,再用新的token进行验证,这样验证就可以通过了,也就不影响服务的正常运行了。代码分析如下:

在上一篇中blog《rest api请求时token的注入》介绍了neutronclient发起http请求的过程。httpclient实际上是SessionClient,因为创建client时传进的session总不是为None,是 keystoneclient.session.Session,所以调用的do_request函数是SessionClient的do_request函数。

class SessionClient(adapter.Adapter):    def request(self, *args, **kwargs):        kwargs.setdefault('authenticated', False)        kwargs.setdefault('raise_exc', False)        content_type = kwargs.pop('content_type', None) or 'application/json'        headers = kwargs.setdefault('headers', {})        headers.setdefault('Accept', content_type)        try:            kwargs.setdefault('data', kwargs.pop('body'))        except KeyError:            pass        if kwargs.get('data'):            headers.setdefault('Content-Type', content_type)        resp = super(SessionClient, self).request(*args, **kwargs)        return resp, resp.text    def do_request(self, url, method, **kwargs):        kwargs.setdefault('authenticated', True)        self._check_uri_length(url)        return self.request(url, method, **kwargs)
do_request函数调用request函数,request函数又调用父类的request函数,父类为adapter.Adapter,其request函数为:

class Adapter(object):    def request(self, url, method, **kwargs):        endpoint_filter = kwargs.setdefault('endpoint_filter', {})        self._set_endpoint_filter_kwargs(endpoint_filter)        if self.endpoint_override:            kwargs.setdefault('endpoint_override', self.endpoint_override)        if self.auth:            kwargs.setdefault('auth', self.auth)        if self.user_agent:            kwargs.setdefault('user_agent', self.user_agent)        if self.connect_retries is not None:            kwargs.setdefault('connect_retries', self.connect_retries)        if self.logger:            kwargs.setdefault('logger', self.logger)        return self.session.request(url, method, **kwargs)

在Adapter函数中,又调用session.request函数,此处session和SessionClient的session是一样的,为keystoneclient.session.Session。其request函数为:

class Session(object):    @utils.positional(enforcement=utils.positional.WARN)    def request(self, url, method, json=None, original_ip=None,                user_agent=None, redirect=None, authenticated=None,                endpoint_filter=None, auth=None, requests_auth=None,                raise_exc=True, allow_reauth=True, log=True,                endpoint_override=None, connect_retries=0, logger=_logger,                **kwargs):        ........        send = functools.partial(self._send_request,                                 url, method, redirect, log, logger,                                 connect_retries)                resp = send(**kwargs)        # handle getting a 401 Unauthorized response by invalidating the plugin        # and then retrying the request. This is only tried once.        if resp.status_code == 401 and authenticated and allow_reauth:                        if self.invalidate(auth):                auth_headers = self.get_auth_headers(auth)                if auth_headers is not None:                    headers.update(auth_headers)                                        resp = send(**kwargs)        if raise_exc and resp.status_code >= 400:            logger.debug('Request returned failure status: %s',                         resp.status_code)            raise exceptions.from_response(resp, method, url)        return resp
从request函数可以看到在第一次send后获取返回的response(resp),如果返回的代码为401,并且authenticated,允许重新认证,则就会进行第二次认证,在发起第二次请求处理,如果第二次请求失败,则就再返回失败结果。












0 0
原创粉丝点击