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 时遇到问题。
这就是我所在的地方;为了开始迁移,我按照以下步骤进行:
我将 Firebase-Auth 添加到 Android 应用程序中,同时应用程序中仍保留有 Gitkit,直到 Firebase-Auth 正常工作。现在我有两个登录按钮,一个用于登录 Firebase,另一个用于“几乎已弃用”的 Gitkit。
在 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_代码
但是,如果您想使用 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/