Thanks for asking this question. I came to this as a complete beginner and there is quite a learning curve. Because I am proxying the Xero signin so I can support multiple domains with one app, I needed to handle the oauth2 stuff manually.
There are hardly any questions on this and it was driving me a bit crazy, so I have added a python answer in case it helps others.
In python3, this is how it can be done:
# using pip install pyjwt[crypto]
import jwt
...
def decode_id_token(self,id_token):
#a method in a class I have, self.client_id is from the Xero app
#decoded_without_verification = jwt.decode(id_token,options={"verify_signature":False})
discovery_url = "https://identity.xero.com/.well-known/openid-configuration/jwks"
jwks_client = jwt.PyJWKClient(discovery_url)
signing_key = jwks_client.get_signing_key_from_jwt(id_token)
decoded = jwt.decode(id_token,signing_key.key,
algorithms=["RS256"],audience=self.client_id)
return decoded
I don't know if there is some way to avoid hardcoding the discovery URL. I got it from this Xero discussion: https://community.xero.com/developer/discussion/115505302