当前位置: 首页 > 知识库问答 >
问题:

谷歌云-使用JWT令牌访问存储API:非法URI错误

何章横
2023-03-14

我尝试使用下面列出的示例对存储API进行JWT调用,并做了如下更改-

def generate_jwt():

"""Generates a signed JSON Web Token using a Google API Service Account."""

now = int(time.time())
sa_email = os.environ["FUNCTION_IDENTITY"]
expiry_length = 3600

# build payload
payload = {
    'iat': now,
    # expires after 'expiry_length' seconds.
    "exp": now + expiry_length,
    # iss must match 'issuer' in the security configuration in your
    # swagger spec (e.g. service account email). It can be any string.
    'iss': sa_email,
    # aud must be either your Endpoints service name, or match the value
    # specified as the 'x-google-audience' in the OpenAPI document.
    'aud': "https://storage.googleapis.com", 
    # sub and email should match the service account's email address
    'sub': sa_email,
    'email': sa_email
    
}
# sign with keyfile
sa_keyfile="cred.json"
signer = google.auth.crypt.RSASigner.from_service_account_file(sa_keyfile)
jwt = google.auth.jwt.encode(signer, payload)
return jwt

在这里叫它

def make_jwt_request(signed_jwt, url="https://storage.googleapis.com/storage/v1/b/BUCKET_NAME"):
"""Makes an authorized request to the endpoint"""
headers = {
    'Authorization': 'Bearer {}'.format(signed_jwt.decode('utf-8')),
    'content-type': 'application/json',
    "Host": "www.googleapis.com",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.content)
response.raise_for_status()

但是获取错误as无法解析指定的URI。非法URI。

我不明白为什么它是一个非法的URI。我尝试了https://googleapis.com/storage/b/BUCKETNMAE,但还是一样的错误。在SO或谷歌文档上找不到任何关于这个的东西。任何想法我在这里做什么错了吗?

共有1个答案

茹元魁
2023-03-14

谷歌云存储不接受签名JWT进行授权。创建签名JWT后,必须将JWT交换为访问令牌。

有关Python的完整示例,请参阅我的答案或我的文章。

def exchangeJwtForAccessToken(signed_jwt):
    '''
    This function takes a Signed JWT and exchanges it for a Google OAuth Access Token
    '''

    auth_url = "https://www.googleapis.com/oauth2/v4/token"

    params = {
        "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
        "assertion": signed_jwt
    }

    r = requests.post(auth_url, data=params)

    if r.ok:
        return(r.json()['access_token'], '')

    return None, r.text
 类似资料:
  • 我是谷歌API新手,几天来我一直在尝试使用服务帐户将内容上传到谷歌云存储桶。我能够做到这一点,但只能使用从谷歌API游乐场获得的临时访问令牌,我需要能够获得新的访问令牌,以便服务帐户能够始终上载内容。 我一直在尝试以下方法,但我一直被拒绝访问,即使有问题的帐户具有“所有者”权限。 答复: 当我运行时,我得到了正确的项目,该帐户是我的工作电子邮件,也是谷歌云的所有者。 提前谢谢!

  • 我找到的签名Google云存储Blob的示例和源代码都需要服务帐户凭据文件(私钥是特定的)。例如: https://cloud.google.com/storage/docs/access-control/signing-urls-with-helpers#storage-签名url获取对象python 但是,由于我遵循此处讨论的授权流程,因此我只有OAuth2.0访问令牌(并且我没有能够访问GC

  • 我正在使用请求将文件上传到谷歌云存储。 请求是: 我得到以下错误作为响应: 我在某处读到,我需要打开谷歌云存储JSON API。是否必须打开谷歌云存储JSON API,或者是否有其他解决方案来修复此错误?

  • 我使用Reactjs创建一个网站并将其托管在Firebase上,并使用google cloud函数上的和设置,以处理函数。网站有一个

  • 我试图设计一个应用程序,从我的谷歌云存储帐户下载适当的声音文件。该应用程序不访问用户帐户,但我自己的帐户。 我的阅读让我相信,最合适的模式是服务账户https://code.google.com/p/google-api-java-client/wiki/OAuth2#Service_Accounts 不幸的是,开发人员决定不提供Android的例子。他们确实提供了一个很好的例子,只是简单的Jav