3

我写了以下代码:

def check_token(token):
    response = requests.get("https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com")
    key_list = response.json()
    decoded_token = jwt.decode(token, key=key_list, algorithms=["RS256"])
    print(f"Decoded token : {decoded_token}")

我正在尝试解码tokenfirebase 客户端提供的内容以在服务器端进行验证。
上面的代码抛出以下异常:

TypeError: Expecting a PEM-formatted key.

我试图不将列表传递给该jwt.decode方法,只传递关键内容,并且我有一个比库更大的错误could not deserialize the Key
我一直在关注这个答案,但我收到了这个错误。

requests转换问题吗?我究竟做错了什么 ?

4

1 回答 1

2

keyin的第二个参数decode()似乎采用字符串值而不是列表。Google API 请求返回一个包含多个键的 dict/map。流程如下:

  1. 从 Google API 端点获取公钥
  2. 然后在没有验证的情况下读取标题以获取kid声明,然后使用它从该字典中获取适当的密钥
  3. 这是一个而不是这个答案X.509 Certificate中的公钥,所以你需要从中获取公钥。

以下功能对我有用:

import jwt
import requests
from cryptography.hazmat.backends import default_backend
from cryptography import x509

def check_token(token):
    n_decoded = jwt.get_unverified_header(token)
    kid_claim = n_decoded["kid"]

    response = requests.get("https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com")
    x509_key = response.json()[kid_claim]
    key = x509.load_pem_x509_certificate(x509_key.encode('utf-8'),  backend=default_backend())
    public_key = key.public_key()

    decoded_token = jwt.decode(token, public_key, ["RS256"], options=None, audience="<FIREBASE_PROJECT_ID>")
    print(f"Decoded token : {decoded_token}")

check_token("FIREBASE_ID_TOKEN")
于 2021-09-25T06:17:25.060 回答