如何从Google脚本向BigQuery发出正确的HTTP请求

问题描述

我正在使用Google脚本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 ...(使用MutantHttpExceptions选项检查完整响应)(第68行,文件“ bigQuery”)

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

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

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

解决方法

使用承载令牌

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}`
  }
};


使用高级服务

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

在使用BigQuery高级服务之前,您必须先enable

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

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

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

上面的方法链与BigQuery API的tables.get方法相对应。