首页 > 解决方案 > 如何从谷歌脚本向 BigQuery 发出正确的 HTTP 请求

问题描述

我正在使用谷歌脚本 API 试图从 BiqQuery 获取表的模式......不知道为什么它这么麻烦。

我正在发送这样的请求:

let url =  'https://bigquery.googleapis.com/bigquery/v2/projects/'+ projectId +'/datasets/'+ datasetId +'/tables/' +tableId; 

 var response = UrlFetchApp.fetch(url)

我收到了这样的回复:

例外:对https://bigquery.googleapis.com的请求失败,返回代码 401。截断的服务器响应:{“错误”:{“代码”:401,“消息”:“请求缺少所需的身份验证凭据。预期 OAuth 2 访问令牌、登录 cookie ...(使用 muteHttpExceptions 选项检查完整响应)(第 68 行,文件“bigQuery”)

我已经能够将数据加载到 bigQuery 了……不知道为什么这不起作用。我查看了清单中的 OAuth 字段,并且脚本确实可以访问 bigQuery ...

将此添加到 UrlFetch 请求的选项字段时也没有成功

var authHeader = 'Basic ' + Utilities.base64Encode(USERNAME + ':' + PASSWORD);
    var options = {
      headers: {Authorization: authHeader}
    }

标签: google-apps-scriptgoogle-bigqueryauthorizationurlfetch

解决方案


使用不记名令牌

BigQuery API 拒绝您的请求的原因是端点需要为以下范围之一提供访问令牌才能工作,并且请求中缺少它:

https://www.googleapis.com/auth/bigquery
https://www.googleapis.com/auth/cloud-platform
https://www.googleapis.com/auth/bigquery.readonly
https://www.googleapis .com/auth/cloud-platform.read-only

这里的实际问题是基本授权方案缺少有关任何声明的信息,仅发送正确的凭据。由于您直接使用UrlFetch服务请求端点,尽管在清单中正确指定了范围,但它们不会被发送过来。

ScriptApp服务现在提供了一种简单的方法来获取有效的不记名令牌,而无需使用 OAuth 2.0 库或从头开始构建流程:getOAuthToken. 将其作为不记名令牌传递给Authorization标头,您应该已准备就绪:

const token = ScriptApp.getOAuthToken();

const options = {
  headers : {
    Authorization : `Bearer ${token}`
  }
};


使用高级服务

作为替代方案,有一个官方高级服务作为 BigQuery REST API 的包装器,它将为您管理身份验证和响应解析。

您必须先启用BigQuery 高级服务,然后才能使用它

另外,请注意高级服务标识符是可配置的,因此您必须引用您选择的标识符。

在您的情况下,该服务可以按如下方式使用(假设您使用了默认BigQuery标识符)。还有第四个类型的参数object包含可选参数(此处未显示):

Bigquery.Tables.get("projectId","datasetId", "tableId");

上面的方法链对应tables.getBigQuery API 的方法。


推荐阅读