Q: how to deal with token refresh?
We have an API which integrates with Sharepoint, where ideally we don't obtain tokens for each API call. But from what I can tell, there are no infra to handle expiring tokens/refreshing them. Should I:
- just accept this, or
- refresh on expiry or
- do a PR for handing refresh or
- did miss something, and handling of this is handled somewhere?
PS. I'm basing this on this from TokenResponse:
def is_valid(self):
return self.accessToken is not None and self.tokenType == 'Bearer'
Seems not to check anything RE expiry
Refresh Tokens can be handled by the msal library. It contains a token cache that can be serialized - SerializableTokenCache and then be stored somewhere safe
I'm not sure Refreshing tokens, or storing these forms part of this library, but an example might be useful.
An example of where I use this, is in the aiohttp_msal library: see here for retrieving these from Redis. Although the typical flow would be renewing client tokens based on the Tokencache stored in an aiohttp_session session (mostly using using Redis for the actual storage)
There are many ways to deal with it, and I’m not arguing that this library should reinvent the wheel, but ideally leverage existing options to deal with expired tokens in some way. I can’t easily see how I would easily inject handling of expired tokens, without touching a fair share of internals of this library?
Not tested, starting from the function in the readme and adding a token_cache. Stored in clear text.
def acquire_token_func():
"""
Acquire token via MSAL
"""
authority_url = 'https://login.microsoftonline.com/{tenant_id_or_name}'
path = pathlib.Path("/my_token_cache.json")
token_cache = SerializableTokenCache()
token_cache.deserialize(path.read_text(encoding="utf8"))
app = msal.ConfidentialClientApplication(
authority=authority_url,
client_id='{client_id}',
client_credential='{client_secret}'
token_cache=token_cache
)
token = app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])
if token_cache.has_state_change:
cstr = token_cache.serialize()
path.write_text(cstr, encoding="utf8")
return token