python - 使用 python-jose 将 Python 后端从 Gitkit 迁移到 Firebase-Auth 以进行 token 验证

标签 python migration jwt firebase-authentication gitkit

Over on GitHub一位乐于助人的 Google 开发人员告诉我

to create a user session, your python backend server only needs a JWT library to verify the Firebase Auth token (signature and audience) in the request and extract the user info from the token payload.

我在验证 token 时遇到问题。

这就是我所在的地方;为了开始迁移,我按照以下步骤进行:

  1. 我将 Firebase-Auth 添加到 Android 应用程序中,同时应用程序中仍保留有 Gitkit,直到 Firebase-Auth 正常工作。现在我有两个登录按钮,一个用于登录 Firebase,另一个用于“几乎已弃用”的 Gitkit。

  2. 在 firebase.com 上,我将 Google 项目导入到新的 Firebase 项目中,因此用户数据库是相同的。我已经成功在 Android 应用程序中使用 Firebase-Auth,能够以已知用户身份登录,并且可以通过调用 mFirebaseAuth.getCurrentUser().getToken(false).getResult().getToken() 成功检索后端服务器所需的 token 。 。它包含相同的 user_id作为 GitKit token 。

现在我正在尝试替换 identity-toolkit-python-client 图书馆 python-jose 。由于我目前没有将 Firebase token 发送到后端,而仅将 Gitkit token 发送到后端,因此我想测试此 python-jose Gitkit token 上的库。

在后端,在调用 GitKit.VerifyGitkitToken() 之前我现在正在打印 jose.jwt.get_unverified_header() 的结果和jose.jwt.get_unverified_claims()为了检查我是否能看到我所期望的。结果很好,我能够按照预期查看 Gitkit token 的内容。

我的问题来自于验证。我无法使用jose.jwt.decode()用于验证,因为我不知道需要使用哪个 key

jose.jwt.decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None)

我从 header 知道算法,并且“aud”字段也存储在声明中,如果这有任何帮助的话。

回到工程师评论

verify the Firebase Auth token (signature and audience)

如何利用我现有的信息来做到这一点?我猜受众是声明中的“aud”字段,但如何检查签名?

一旦我删除了服务器上的 Gitkit 依赖项,我将继续迁移。

据我所知,GitKit 库显然对 Google 服务器进行了“RPC”调用以进行验证,但我可能是错的。

那么,Gitkit token 验证的 key 和 Firebase token 验证的 key 分别是哪一个?

最佳答案

可以获取 key

对于 Firebase,位于 ojit_代码

对于 Gitkit,位于 ojit_代码

使用 Google 的 https://www.googleapis.com/robot/v1/metadata/x509/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="23504640565146574c48464d63505a5057464e0d44504651554a40464240404c564d570d404c4e" rel="noreferrer noopener nofollow">[email protected]</a> 库使验证变得非常容易。

但是,如果您想使用 https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys 而不是 oauth2client ,则 you first need to convert the PEM certificate into an RSA public key (更新:此问题已修复,对于 Firebase,此问题现在由库处理,请向下滚动到此评论之前的 GitHub 链接的末尾。不确定 Gitkit)。这个公钥就是需要使用的 key 。并且受众不应该从 JWT header 中提取,而是硬编码到源代码中,其中在 Firebase 中受众是项目 ID,在 Gitkit 中它是以下之一OAuth 2.0 客户端 ID,可以在 Google 开发者控制台凭据部分找到。

JWT header 中的 python-jose 用于选择适当的证书,该证书将用于获取用于执行验证的 key 。

  # firebase
  # target_audience = "firebase-project-id"
  # certificate_url = 'https://www.googleapis.com/robot/v1/metadata/x509/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="10637573656275647f7b757e5063696364757d3e77637562667973757173737f657e643e737f7d" rel="noreferrer noopener nofollow">[email protected]</a>'

  # gitkit
  target_audience = "123456789-abcdef.apps.googleusercontent.com" # (from developer console, OAuth 2.0 client IDs)
  certificate_url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys'

  response = urllib.urlopen(certificate_url)
  certs = response.read()
  certs = json.loads(certs)
  print "CERTS", certs
  print ''
  print ''

  # -------------- verify via oauth2client
  from oauth2client import crypt
  crypt.MAX_TOKEN_LIFETIME_SECS = 30 * 86400 # according to https://github.com/google/identity-toolkit-python-client/blob/master/identitytoolkit/gitkitclient.py
  print "VALID TOKEN", crypt.verify_signed_jwt_with_certs(idtoken, certs, target_audience)  
  print ''
  print ''

  # -------------- verify via python-jose
  from jose import jwt
  unverified_header = jwt.get_unverified_header(idtoken)
  print "UNVERIFIED HEADER", unverified_header
  print ''
  print ''
  unverified_claims = jwt.get_unverified_claims(idtoken)
  print "UNVERIFIED CLAIMS", unverified_claims
  print ''
  print ''
  from ssl import PEM_cert_to_DER_cert
  from Crypto.Util.asn1 import DerSequence
  pem = certs[unverified_header['kid']]
  der = PEM_cert_to_DER_cert(pem)
  cert = DerSequence()
  cert.decode(der)
  tbsCertificate = DerSequence()
  tbsCertificate.decode(cert[0])
  rsa_public_key = tbsCertificate[6]
  print "VALID TOKEN", jwt.decode(idtoken, rsa_public_key, algorithms=unverified_header['alg'], audience=target_audience)

关于python - 使用 python-jose 将 Python 后端从 Gitkit 迁移到 Firebase-Auth 以进行 token 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39123568/

相关文章:

python - 为什么人们会使用 globals() 来定义变量

php - 对于 Drupal 来说,能够在上线时将其移动到不同服务器的最佳开发环境是什么?

node.js - 如何使用 NVM 将全局 cordova 包(acorn-node)迁移到旧 Node 版本?

java - 如何使用 Java 验证 Azure B2C ID token 的 JWT 签名?

jwt - Keycloak 如何在 id token 中编码组成员身份

python - 如何在pyplot中自动标注最大值

python - 对python的LOAD_FAST/STORE_FAST感到困惑

python - 沿特定维度从 ndarray 中减去矩阵而不重新整形

ios - 核心数据迁移 : How to populate new attribute?

javascript - 在 Angular SPA 中存储凭证