验证Android后端调用Python中的Id令牌

时间:2014-04-30 20:04:17

标签: android python-3.x google-oauth google-api-client google-api-python-client

正如here所述,我正在尝试验证Android应用程序传递给运行python3的服务器的令牌。

我想验证传递的令牌。问题是我在google-api-python-client库不支持的服务器上运行python3。我使用pyjwt和请求库找到了以下解决方法: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

我的两个问题是:

  1. 有没有人知道在python3中有不同和/或更好的现有解决方案?
  2. 上述解决方案是否完整?

2 个答案:

答案 0 :(得分:1)

经过几个小时的谷歌搜索和一些反复试验后,我就是这样做的。

依赖关系

pip install cryptography PyJWT requests

代码

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

修改

我刚刚在python中使用Google provides an example库实现了oauth2client

答案 1 :(得分:0)

Google API最近被移植到Python 3x并包含jwt验证。您可以访问here

至于你的工作我唯一要强调的是Stefan在你发布的链接上做的同样的事情。这是您在jwt解码调用中使用verify = False导致的安全漏洞。