Using Xero OAuth2 with Python3/requests
Xero has an interesting way of authenticating with its API. Sadly, without going through their API code/SDK, this mechanism isn’t super well-documented. The bare bones: It relies on a previously issued token to create a new access token, not indifferent to a rolling code.
Unless your app is in an event loop (have a look at Xero’s Kitchen Sink example code here), it’s necessary to store the refresh token somewhere (Redis would be ideal?) but alas, in the below example it’s being stored on the filesystem. All the usual security cavets apply so use at your own risk.
Addendum: So maybe I was a little too quick to write off Xero’s documentation. I did manage to come across this which does go into detail with a high level overview of the OAuth2 flow. This also shows (in Step 3.) how to connect your app and get an initial Refresh Token.
import requests
import base64
CLIENT_ID="xxxxx"
CLIENT_SECRET="xxxxx"
def refresh_xero_token():
""" Required to authenticate against Xero's API for requests
"""
refresh_url = "https://identity.xero.com/connect/token"
old_token = open('.oldtoken','r').read()
auth_string = f"{CLIENT_ID}:{CLIENT_SECRET}"
token = base64.urlsafe_b64encode(auth_string.encode()).decode()
headers = {
'Authorization': f"Basic {token}",
'Content-Type': 'application/x-www-form-urlencoded',
}
data = {
'grant_type': 'refresh_token',
'refresh_token': old_token
}
res = requests.post(refresh_url, headers=headers, data=data)
open('.oldtoken.txt','w').write(res.json()["refresh_token"])
access_token = res.json()["access_token"]
return access_token