Google 服务帐号:API 返回错误:TypeError: source.hasOwnProperty is not a function after a hour

Posted

技术标签:

【中文标题】Google 服务帐号:API 返回错误:TypeError: source.hasOwnProperty is not a function after a hour【英文标题】:Google service account: The API returned an error: TypeError: source.hasOwnProperty is not a function after an hour 【发布时间】:2019-12-17 17:50:52 【问题描述】:

我在一个项目中添加了谷歌云服务帐户及其工作。但问题是一个小时后(我认为),我得到了这个错误:

The API returned an error: TypeError: source.hasOwnProperty is not a function
Internal Server Error

我需要重新启动应用程序才能使其正常工作。

在这个*** post,我发现了这个:

一旦您获得访问令牌,它就会以同样的方式处理 - 并且是 预计将在 1 小时后到期,届时新的访问令牌将 需要被请求,这对于服务帐户意味着创建和 签署新的断言。

但没有帮助。 我正在使用 Node js 和亚马逊特工:

我用来授权的代码:


        const jwtClient = new google.auth.JWT(
            client_email,
            null,
            private_key,
            scopes
        );

        jwtClient.authorize((authErr) =>
            if(authErr)
                const deferred = q.defer();
                deferred.reject(new Error('Google drive authentication error, !'));
            
        );

有什么想法吗?

提示:AWS Secret 中是否有任何策略可以访问 Secret 或 Google Cloud 中是否有访问服务帐户的策略?例如本地访问还是在线访问?

【问题讨论】:

【参考方案1】:

[注意:您正在使用服务帐户访问 Google 云端硬盘。服务帐户将拥有自己的 Google Drive。这是您的意图还是您的目标是与服务帐户共享您的 Google 云端硬盘?]

AWS 机密或谷歌中是否有任何访问机密的策略 云访问服务帐户?例如在本地访问或 在线?

我不确定你在问什么。 AWS 有 IAM 策略来控制秘密管理。由于您能够从存储的机密中创建签名 JWT,因此我认为这不是问题。 Google 没有关于访问服务帐户的政策 - 如果您拥有服务帐户 JSON 密钥材料,您可以执行服务帐户被授权执行的任何操作,直到服务帐户被删除、修改等。

现在讨论真正的问题。

您的 Signed JWT 已过期,您需要创建一个新的。您需要跟踪您创建的令牌的生命周期,并在令牌过期之前重新创建/刷新令牌。 Google 世界中的默认到期时间是 3,600 秒。由于您正在创建自己的令牌,因此您的令牌周围没有“包装”代码来处理过期问题。

您遇到的错误是由代码崩溃引起的。由于您没有包含您的代码,我无法告诉您在哪里。但是,解决方案是捕获错误,以便管理过期异常。

我建议您使用服务帐户创建客户端,而不是使用签名 JWT 创建 Google Drive 客户端。令牌过期和刷新将为您管理。

很少有 Google 服务仍然支持签名 JWT(您的代码正在使用它)。您应该切换到使用服务帐户,该帐户以签名的 JWT 开始,然后在内部将其交换为 OAuth 2.0 访问令牌。

您可以使用多个库。以下任何一项都将提供您应该使用的功能,而不是制作您自己的签名 JWT。

https://github.com/googleapis/google-auth-library-nodejs

https://github.com/googleapis/google-api-nodejs-client

以下代码是一个“示例”,并非用于测试和调试。更改此示例中的 scopes 以匹配您的要求。删除我加载 service-account.json 文件的部分并替换为您的 AWS Secrets 代码。使用您所需的功能填写代码。如果您遇到问题,请使用您编写的代码和详细的错误消息创建一个新问题。

const GoogleAuth = require('google-auth-library');
const google = require('googleapis');

const key = require('service-account.json');

/**
 * Instead of specifying the type of client you'd like to use (JWT, OAuth2, etc)
 * this library will automatically choose the right client based on the environment.
 */
async function main() 
  const auth = new GoogleAuth(
    credentials: 
      client_email: key.client_email,
      private_key: key.private_key,
    ,
    scopes: 'https://www.googleapis.com/auth/drive.metadata.readonly'
  );

  const drive = google.drive('v3');

  // List Drive files.
  drive.files.list( auth: auth , (listErr, resp) => 
    if (listErr) 
      console.log(listErr);
      return;
    
    resp.data.files.forEach((file) => 
      console.log(`$file.name ($file.mimeType)`);
    );
  );


main()

【讨论】:

您的解决方案有效,抱歉延迟反馈,我正在测试您的解决方案是否适合我 我唯一无法理解的是:this.credentials = refresh_token: 'jwt-placeholder', expiry_date: 1; from https://github.com/googleapis/google-auth-library-nodejs/blob/master/src/auth/jwtclient.ts。这个是来做什么的?这是否意味着令牌会在 1 天后过期? @HadiRasouli - 您的评论中没有足够的信息。请创建一个新问题。注意:Google 令牌会在一小时后过期,而不是一天。

以上是关于Google 服务帐号:API 返回错误:TypeError: source.hasOwnProperty is not a function after a hour的主要内容,如果未能解决你的问题,请参考以下文章

Google API 服务帐号

查询 Google Play Developer API 时出现意外错误。请检查您是不是使用了正确的服务帐号

Google Drive API、Oauth 和服务帐号

多语言 Google 翻译 API 正在返回 (503) 服务器不可用

如何使用 Google 服务帐户通过 Activity API 检索 Google Drive 活动?

GCP IAM REST API 服务帐号密钥问题