From reading various documents it seems like authorization is optionally required by oauth2 providers for refresh token requests. I'm working with the FitBit API that appears to require authorization.
I'm following the instructions here for refreshing a token with requests-oauthlib
:
https://requests-oauthlib.readthedocs.io/en/latest/oauth2_workflow.html#refreshing-tokens
Some setup code (not what I am using, but you get the idea:
>>> token = {
... 'access_token': 'eswfld123kjhn1v5423',
... 'refresh_token': 'asdfkljh23490sdf',
... 'token_type': 'Bearer',
... 'expires_in': '-30', # initially 3600, need to be updated by you
... }
>>> client_id = r'foo'
>>> refresh_url = 'https://provider.com/token'
>>> protected_url = 'https://provider.com/secret'
>>> # most providers will ask you for extra credentials to be passed along
>>> # when refreshing tokens, usually for authentication purposes.
>>> extra = {
... 'client_id': client_id,
... 'client_secret': r'potato',
... }
>>> # After updating the token you will most likely want to save it.
>>> def token_saver(token):
... # save token in database / session
from requests_oauthlib import OAuth2Session
client = OAuth2Session(client_id, token=token, auto_refresh_url=refresh_url,
auto_refresh_kwargs=extra, token_updater=token_saver)
r = client.get(protected_url)
However, with this call I'm getting:
MissingTokenError: (missing_token) Missing access token parameter.
I know my token is expired, but why isn't the refresh working?
The library is broken in this regard. See #379.
You can work around it something like this:
def _wrap_refresh(func):
def wrapper(*args, **kwargs):
kwargs['auth'] = (client_id, client_secret)
kwargs.pop('allow_redirects', None)
return func(*args, **kwargs)
return wrapper
client = OAuth2Session(client_id, token=token,
auto_refresh_url=refresh_url,
token_updater=token_saver)
client.refresh_token = _wrap_refresh(client.refresh_token)