【发布时间】:2023-12-05 10:39:01
【问题描述】:
我的客户有一个在 Google 云上运行的 GraphQL API。
我已收到用于身份验证以及访问 gcloud 命令行工具的服务帐户。
当像这样使用 gcloud 命令行时:
gcloud auth print-identity-token
我可以生成一个可用于向 api 发出 post 请求的令牌。这很有效,我可以从邮递员、失眠症和我的 nodejs 应用程序向 api 发出成功的发布请求。
但是,当我将 JWT 身份验证与“googleapis”或“google-auth”npm 库一起使用时:
var { google } = require('googleapis')
let privatekey = require('./auth/google/service-account.json')
let jwtClient = new google.auth.JWT(
privatekey.client_email,
null,
privatekey.private_key,
['https://www.googleapis.com/auth/cloud-platform']
)
jwtClient.authorize(function(err, _token) {
if (err) {
console.log(err)
return err
} else {
console.log('token obj:', _token)
}
})
这会输出一个“承载”令牌:
token obj: {
access_token: 'ya29.c.Ko8BvQcMD5zU-0raojM_u2FZooWMyhB9Ni0Yv2_dsGdjuIDeL1tftPg0O17uFrdtkCuJrupBBBK2IGfUW0HGtgkYk-DZiS1aKyeY9wpXTwvbinGe9sud0k1POA2vEKiGONRqFBSh9-xms3JhZVdCmpBi5EO5aGjkkJeFI_EBry0E12m2DTm0T_7izJTuGQ9hmyw',
token_type: 'Bearer',
expiry_date: 1581954138000,
id_token: undefined,
refresh_token: 'jwt-placeholder'
}
但是,这个不记名令牌不能像上面那样工作,并且在发出与 gcloud 命令“gcloud auth print-identity-token”相同的请求时总是给出“未经授权的错误 401”。
请帮忙,我不确定为什么第一个不记名令牌有效,但使用 JWT 生成的不有效。
编辑
我也尝试过获取身份令牌,而不是像这样的访问令牌:
let privatekey = require('./auth/google/service-account.json')
let jwtClient = new google.auth.JWT(
privatekey.client_email,
null,
privatekey.private_key,
[]
)
jwtClient
.fetchIdToken('https://my.audience.url')
.then((res) => console.log('res:', res))
.catch((err) => console.log('err', err))
这会打印一个身份令牌,但是,使用它也只会给出“401 unauthorized”消息。
编辑以显示我如何调用端点
顺便说一句,下面的这些方法中的任何一个都可以使用命令行身份令牌,但是当通过 JWT 生成时,它会返回 401
方法一:
const client = new GraphQLClient(baseUrl, {
headers: {
Authorization: 'Bearer ' + _token.id_token
}
})
const query = `{
... my graphql query goes here ...
}`
client
.request(query)
.then((data) => {
console.log('result from query:', data)
res.send({ data })
return 0
})
.catch((err) => {
res.send({ message: 'error ' + err })
return 0
})
}
方法 2(使用我用 google-auth 创建的“授权”客户端):
const res = await client.request({
url: url,
method: 'post',
data: `{
My graphQL query goes here ...
}`
})
console.log(res.data)
}
【问题讨论】:
-
我认为您的问题是身份令牌受众。在你的最后一个例子中,观众是什么?此代码是在 Cloud Run 中运行还是您正在调用 Cloud Run 服务?如果您正在调用 Cloud Run 服务,则受众值必须与如下所示的
Assigned by Cloud Run网址匹配:https://example-ylyxpergiq-uc.a.run.app,您可以从 Google Cloud Console 复制该网址。您的第一个示例将永远不会工作,因为它会生成访问令牌。您的第二个示例是创建正确类型的令牌,即身份令牌。 -
使用 jwt.io 解码身份令牌并在您的问题中显示这些值(屏蔽项目和电子邮件等敏感信息)。
-
最后一项,编辑您的问题并显示您如何在代码中调用端点。
-
@JohnHanley 确定
-
您在我的第一条评论中没有回答我的问题。您没有从我的第二条评论中提供身份令牌信息。如果没有详细信息,您将继续得到只是猜测的答案。
标签: google-cloud-platform gcloud google-api-nodejs-client google-cloud-run