Reputation: 19104
As explained here, I am trying to verify a token that is passed, by an Android app, to a server running python3.
I want to verify the passed token. The trouble is that I am running python3 on the server which is not supported by the google-api-python-client library. I found the following workaround, using the pyjwt and requests libraries, from this site:
import json
import jwt
import requests
GOOGLE_CERTS_URI = 'https://www.googleapis.com/oauth2/v1/certs'
class GoogleIdToken(object):
def __init__(self):
self._certs = {}
self._token = {}
def getCerts(self):
cert = requests.get(GOOGLE_CERTS_URI)
if cert.status_code == 200:
return json.loads(cert.content)
def isValid(self, token, audience, clientId=None):
self._certs = self.getCerts()
for key in self._certs:
try:
token = jwt.decode(token, key=self._certs[key], verify=False)
if 'email' in token and 'aud' in token:
if token['aud'] == audience and (clientId == token['cid'] if clientId is not None else True):
self._token = token
return True
except Exception, e:
print("Error decoding: %s" % e.message)
return False
My two questions are:
Upvotes: 4
Views: 1371
Reputation: 1333
After a few hours of googling around and some trial and error, this is how I ended up doing it.
Dependencies
pip install cryptography PyJWT requests
Code
import jwt, requests
from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.backends import default_backend
GOOGLE_CERTS_URI = 'https://www.googleapis.com/oauth2/v1/certs'
def verify_id_token(id_token, audience):
certs = requests.get(GOOGLE_CERTS_URI).json()
for cert in certs.values():
cert = str.encode(cert)
cert_obj = load_pem_x509_certificate(cert, default_backend())
pub_key = cert_obj.public_key()
try:
return jwt.decode(id_token, pub_key, algorithm='RS256',
audience=audience)
except (jwt.exceptions.DecodeError,
jwt.exceptions.ExpiredSignatureError) as e:
pass
EDIT
I just realized Google provides an example in python for that, using their oauth2client library.
Upvotes: 2
Reputation: 1154
The Google API was recently ported to Python 3x and includes jwt verification. You can access it here.
As for your work around the only thing I'd highlight is the same point that Stefan made on the link you posted. That being the security vulnerability you're introducing as a result of having verify=False in your jwt decode call.
Upvotes: 0