使用 jwt 调用 google api 以对原始端点进行服务到服务调用的工作节点示例?
Posted
技术标签:
【中文标题】使用 jwt 调用 google api 以对原始端点进行服务到服务调用的工作节点示例?【英文标题】:Working node example of calling google api with jwt for service-to-service call to raw endpoint? 【发布时间】:2019-03-23 09:27:39 【问题描述】:我一直在尝试调用jobs.Insert bigquery rest api 端点和节点(jobs.Insert 方法似乎没有在bigquery 节点库中公开)。
我已经设置了服务到服务的东西,这样我就可以成功调用 bigquery 节点库具有的方法(创建包含私钥等的 json 文件以进行服务到服务)服务调用)。
据我所知,我应该能够使用签名的 jwt 作为承载令牌直接调用其余 api,而无需经过两步 OAuth 过程。
我有东西可以签署 jwt,但仍然遇到身份验证错误,尝试通过 curl (作为第一步)调用原始 api,例如
curl -H "Authorization: Bearer my_signed_jwt" https://www.googleapis.com/bigquery/v2/projects/my_project_id/datasets
("请求具有无效的身份验证凭据。需要 OAuth 2 访问令牌、登录 cookie 或其他有效的身份验证凭据。"
有人有这样做的例子吗?可能只是缺少一个简单的东西,一个工作示例会很明显。
谢谢
【问题讨论】:
由于 Google 有 2 个主要客户端库,因此了解您使用的是哪一个非常重要,请在其中一个包上查看此问题 ***.com/q/54815207/1031958。如果你正在使用它,你需要一个服务帐户,如果你想要 ouath2,你需要使用 Googleapi。 嗨@TamirKlein 谢谢 - 我会再做一遍,特别是关于我使用服务帐户的不同库,看起来应该可以使用签名的 jwt 作为在这种情况下,access_token 直接用于 bigquery 其余端点,而无需先调用 outh2 端点来获取 access_token。也许我的 jwt 很糟糕,我需要确保它里面有正确的东西。顺便说一句,您能否解决您的问题? fyi 我向 bigquery 添加了一个功能请求,以将 jobs.insert 添加到 bigquery api (issuetracker.google.com/issues/129168463) 并且它已经分配。希望从中获得更多有关它的信息。 【参考方案1】:您可以使用这个工作示例
-
初始化
query
对象
初始化oAuth2
对象
致电bigQuery.Jobs.insert
if (!global._babelPolyfill)
var a = require("babel-polyfill")
import google from 'googleapis'
let bigQuery = google.bigquery("v2")
describe('Check API', async () =>
it('Test query', async () =>
let result = await test('panada')
)
async function test(p1)
try
let query = `SELECT url FROM \`publicdata.samples.github_nested\`
WHERE repository.owner = 'panada'`
let auth = getBasicAuthObj()
auth.setCredentials(
access_token: "myAccessToken",
refresh_token: "myRefreshToken"
)
let request =
"projectId": "myProject",
auth,
"resource":
"projectId": "myProject",
"configuration":
"query":
query,
"useLegacySql": false
,
"dryRun": false
console.log(`query is: $query`)
let result = await callBQ(request) //Check JOB status to make sure it's done
console.log(`result is: $JSON.stringify(result.data)`)
result.forEach((row, index) =>
console.log(`row number $index, url is: $row.url`)
)
catch (err)
console.log("err", err)
/**
* Call BigQuery jobs.insert
* @param request
* @returns Promise
*/
async function callBQ(request)
debugger
console.log("request", request)
try
let result = await bigQuery.jobs.insert(request, request)//, (err, results) =>
console.log(`All good.....`)
return result
catch (e)
console.log(`Failed to run query: $e`)
/**
* Create oAuth object
* @returns OAuth2Client
*/
function getBasicAuthObj()
let clientId = 'myClientId'
let clientSecret = 'mySecret'
let redirectUrl = 'url'
return new google.auth.OAuth2(
clientId,
clientSecret,
redirectUrl
)
)
注意:您需要将此行添加到您的package.json
"googleapis": "34.0.0"
【讨论】:
嘿,谢谢@TamirKlein - 获取访问令牌和刷新令牌是我想要做的两个主要事情,我还没有澄清(通过节点运行,而不是在网络浏览器中运行) - 你是建议在您的示例中在 google 控制台中配置回调 url?我还(在某处)读到,您可以使用签名的 jwt 而无需经过该过程。关于如何为 api 调用获取适当的访问和刷新令牌,我已经看到了许多尚未在我脑海中具体具体化的方法,这对我来说目前是关键的缺失部分。 好的 - 我能够通过类似这样的方式使用 jwt 获取访问令牌和刷新令牌(抱歉格式化,无法输入换行符): const JWT = require('google-授权库'); var jwt = new JWT(jsonObjectFromGoogleKeyEtcFile.client_email, null, jsonObjectFromGoogleKeyEtcFile.private_key, scopes); jwt.authorize(function (err, result) callbackWithErrAndResult(err, result.access_token, result.refresh_token); );【参考方案2】:好的 - 关于我最初的问题的技巧与获取用于 api 调用的访问令牌有关。
const JWT = require('google-auth-library');
function getJWTResultWithAccessAndRefreshToken(jsonObjectFromGoogleKeyEtcFile,
callbackWithErrAndResult)
var scopes = [
"https://www.googleapis.com/auth/bigquery",
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/devstorage.full_control",
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/devstorage.read_write"
];
var jwt = new JWT(
jsonObjectFromGoogleKeyEtcFile.client_email,
null,
jsonObjectFromGoogleKeyEtcFile.private_key,
scopes);
jwt.authorize(function (err, result)
callbackWithErrAndResult(err, result.access_token, result.refresh_token);
);
这里,jsonObjectFromGoogleKeyEtcFile 是您在 Google Cloud Platform APIs & Services 页面中生成“服务帐户密钥”/Credentials 时获得的 json 文件中的 json 对象。
生成的 access_token 可用于进行如下调用 - 有效 - 我使用了上面函数中的 access_token,并从 jsonObjectFromGoogleKeyEtcFile 的 project_id 属性中获取了 projectId:
curl -H "Authorization: Bearer generated_via_jwt_access_token" \
https://www.googleapis.com/bigquery/v2/projects/projectId/datasets
有趣的是,你也得到了一个 refresh_token,但它的值是“jwt-placeholder”
哇哦。
【讨论】:
以上是关于使用 jwt 调用 google api 以对原始端点进行服务到服务调用的工作节点示例?的主要内容,如果未能解决你的问题,请参考以下文章
尝试使用 Google Drive API 的错误 JWT 签名
尝试连接到 Google Oauth for google API 时 JWT 无效
用于向 Google API (Swift) 验证服务帐户的 JWT 签名无效