You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang通过HTTP调用Cloud Function遇401未授权问题求助

Cloud Function调用另一个Cloud Function返回401未授权的解决方案

你的代码问题在于直接发起的HTTP请求没有携带Google身份验证令牌,即使调用方服务账号拥有Cloud Functions Invoker权限,目标Cloud Function也无法识别调用者身份,因此返回401错误。

要解决这个问题,需要为请求附加有效的ID令牌,以下是修改后的完整Go代码:

package main

import (
	"bytes"
	"fmt"
	"net/http"
	"os"

	"google.golang.org/api/idtoken"
)

func main() {
	// 目标Cloud Function URL
	targetURL := "https://[REGION]-[PROJECT_ID].cloudfunctions.net/[FUNCTION_NAME]"

	// 请求体
	requestBody := []byte(`{"name": "John"}`)

	// 创建ID令牌客户端,指定目标函数的受众(即目标URL)
	tokenClient, err := idtoken.NewClient(os.Stdout, targetURL)
	if err != nil {
		panic(fmt.Sprintf("Failed to create ID token client: %v", err))
	}

	// 创建POST请求
	req, err := http.NewRequest("POST", targetURL, bytes.NewBuffer(requestBody))
	if err != nil {
		panic(fmt.Sprintf("Failed to create request: %v", err))
	}

	// 设置请求头为JSON格式
	req.Header.Set("Content-Type", "application/json")

	// 使用tokenClient发送请求(自动附加ID令牌到Authorization头)
	resp, err := tokenClient.Do(req)
	if err != nil {
		panic(fmt.Sprintf("Failed to send request: %v", err))
	}
	defer resp.Body.Close()

	// 读取并打印响应
	var respBody bytes.Buffer
	_, err = respBody.ReadFrom(resp.Body)
	if err != nil {
		panic(fmt.Sprintf("Failed to read response: %v", err))
	}
	fmt.Println(respBody.String())
}

关键说明:

  • 使用idtoken.NewClient创建的客户端会自动获取并附加ID令牌到请求的Authorization头,格式为Bearer <token>
  • 确保调用方Cloud Function的服务账号已被授予Cloud Functions Invoker角色(针对目标函数或项目级)
  • 目标函数的受众URL必须准确,无需添加额外路径(如果目标函数有路径参数,受众仍使用基础URL)
  • 代码中已处理请求头的Content-Type设置,确保JSON体被正确解析

内容的提问来源于stack exchange,提问作者Alex Weber Lopes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 04:53:09