3

如解釋here,我試圖驗證由Android應用程序傳遞給運行python3的服務器的令牌。驗證身份驗證令牌在Android後端調用Python

我想驗證傳遞的令牌。麻煩的是,我在服務器上運行python3,但不支持google-api-python-client庫。我發現了以下解決方法:使用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. 上述解決方案是否完整?
+0

您是否找到了更好的解決方案? – drfence

+0

不,我從來沒有找到一個好的解決方案。 – Alex

+0

這是否仍適用於您或Google改變了任何內容?我自己尋找本地/自己的實現。谷歌圖書館非常臃腫。 –

回答

0

Google API最近被移植到Python 3x幷包含jwt驗證。您可以訪問它here

至於你的工作,我要強調的唯一事情就是Stefan在你發佈的鏈接上提出的觀點。這是您在jwt解碼調用中驗證= False後引入的安全漏洞。

+0

謝謝 - 我找到了端口,但我希望避免使用非官方的庫,這是如此臃腫(爲我的目的,我只需要幾個方法)。我考慮google-api-python-client庫的唯一原因是因爲我認爲它會有LTS。 此外,儘管我沒有嘗試過,但是由於PyJWT現在支持RS256,所以上述解決方法中的驗證kwarg看起來可以是True值。 – Alex

0

經過幾個小時的谷歌搜索和一些試驗和錯誤,這是我最終做到這一點。

依賴

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 

編輯

我才意識到Google provides an example的Python爲是,使用他們的oauth2client庫。