Google cloud platform Google function HTTP触发器-服务器到服务器的身份验证问题(带有服务帐户)

Google cloud platform Google function HTTP触发器-服务器到服务器的身份验证问题(带有服务帐户),google-cloud-platform,google-cloud-functions,google-authentication,google-cloud-iam,server-to-server,Google Cloud Platform,Google Cloud Functions,Google Authentication,Google Cloud Iam,Server To Server,我想做什么:从我的服务器/机器调用google函数,并通过(简单的)身份验证限制它的使用 我使用什么:Node.js,用于身份验证的库 我做了什么/尝试了什么: 1) 在谷歌云功能中创建了一个项目 2) 创建了一个简单的谷歌函数 exports.helloWorld = (req, res) => { let message = req.query.message || req.body.message || 'Hello World!'; res.status(200).sen

我想做什么:从我的服务器/机器调用google函数,并通过(简单的)身份验证限制它的使用

我使用什么:Node.js,用于身份验证的库

我做了什么/尝试了什么

1) 在谷歌云功能中创建了一个项目

2) 创建了一个简单的谷歌函数

 exports.helloWorld = (req, res) => {
  let message = req.query.message || req.body.message || 'Hello World!';
  res.status(200).send(message);
};
3) 设置我的自定义服务帐户

4) 启用的api: -云函数API -IAM服务帐户凭据API -云运行API -计算引擎API -IAM服务帐户凭据API

5) 给予我的服务器帐户必要的授权(项目所有者、云功能管理员、IAM项目管理员…(需要更多吗?)

6) 从我的服务帐户生成密钥并以json格式保存

NB:在获得allUser许可(无需授权)的情况下,我可以毫无问题地呼叫我的端点

7) 从我的项目中,我试图以这种方式验证我的函数

const { JWT } = require('google-auth-library');
const fetch = require('node-fetch');
const keys = require('./service-account-keys.json');


async function callFunction(text) {
  const url = `https://europe-west1-myFunction.cloudfunctions.net/test`;

  const client = new JWT({
    email: keys.client_email,
    keyFile: keys,
    key: keys.private_key,
    scopes: [
      'https://www.googleapis.com/auth/cloud-platform',
      'https://www.googleapis.com/auth/iam',
    ],
  });

  const res = await client.request({ url });
  const tokenInfo = await client.getTokenInfo(client.credentials.access_token);

  try {
    const response = await fetch(url, {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${client.credentials.access_token}`,
      },
    });
    if (response.status !== 200) {
      console.log(response);
      return {};
    }
    return response.json();
  } catch (e) {
    console.error(e);
  }
} 
ℹ️ 如果我尝试在client.request()url上传递函数()的名称,我没有收到错误,但是当使用在fetch调用中获得的JWT令牌时,我收到了相同的错误

结果

 Error: 
<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>401 Unauthorized</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Unauthorized</h1>
<h2>Your client does not have permission to the requested URL <code>/test1</code>.</h2>
<h2></h2>
</body></html>
❓ 我如何调用具有任何保护的google函数来阻止任何人使用它?(我不需要特定的安全性,只是随机用户不使用)
提前感谢您的帮助

当您调用私有函数(或私有云运行)时,您必须使用谷歌签名的身份令牌

在代码中,使用访问令牌

      headers: {
        Authorization: `Bearer ${client.credentials.access_token}`,
      },
当您必须请求Google Cloud API而不是您的服务时,Access token才有效

而且谷歌签名很重要,因为你可以很容易地用谷歌认证库生成一个自签名身份令牌,但它不起作用

你有代码示例,如果你想试试的话,我会告诉你

**编辑**

我做了一个例子,即使我从不喜欢Javascript,我也不得不承认我很嫉妒!!它在节点中非常简单

这里是我的工作示例

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

async function main() {
    // Define your URL, here with Cloud Run but the security is exactly the same with Cloud Functions (same underlying infrastructure)
    const url = "https://go111-vqg64v3fcq-uc.a.run.app"
    // Here I use the default credential, not an explicit key like you
    const auth = new GoogleAuth();
    //Example with the key file, not recommended on GCP environment.
    //const auth = new GoogleAuth({keyFilename:"/path/to/key.json"})

    //Create your client with an Identity token.
    const client = await auth.getIdTokenClient(url);
    const res = await client.request({url});
    console.log(res.data);
}

main().catch(console.error);

注意:只有服务帐户才能生成和使用访问群体的身份令牌。如果您在本地计算机上,请不要使用默认凭据模式的用户帐户。

您是否已将
服务帐户令牌创建者
服务帐户用户
添加到您的服务帐户中?可以找到完整的信息。好的,谢谢回复。我开始猜测不需要访问令牌,但我不确定从文档中看到,要获得id令牌,必须使用IAP。那么,创建一个应用程序引擎并验证一个服务帐户?难道没有更直接的方法来获取令牌id吗?谷歌功能应该是创建“微服务”的最简单方式,但它变得更加复杂