我有一个应用程序引擎项目。
我还有一个谷歌云功能。
我想称之为应用引擎项目中的谷歌云功能。我似乎就是无法让它发挥作用。
是的,如果我将函数完全公开(即将云函数设置为"允许所有流量">并为"allUsers"创建规则以允许调用该函数(,它就可以工作了。但如果我限制这两个设置中的任何一个,它会立即停止工作,我会得到403。
应用程序和函数在同一个项目中,所以我至少认为将函数设置为"仅允许内部流量"应该可以正常工作,前提是我有一个允许"allUsers"调用函数的规则。
这是怎么回事?通常如何从谷歌应用引擎中调用(非公共(谷歌云功能?
您需要一个auth头来ping到函数url。它应该看起来像:
headers = {
....
'Authorization': 'Bearer some-long-hash-token'
}
以下是如何获得代币:
import requests
token_response = requests.get(
'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=' +
'https://[your zone]-[your app name].cloudfunctions.net/[your function name]',
headers={'Metadata-Flavor': 'Google'})
return token_response.content.decode("utf-8")
"仅允许内部通信"无法按预期工作。我的应用程序引擎应用程序与函数在同一个项目中,它不起作用。我不得不打开"允许所有流量",并使用头方法。
示例:
def get_access_token():
import requests
token_response = requests.get(
'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=' +
'https://us-central1-my_app.cloudfunctions.net/my_function',
headers={'Metadata-Flavor': 'Google'})
return token_response.content.decode("utf-8")
def test():
url_string = f"https://us-central1-my_app.cloudfunctions.net/my_function?message=it%20worked"
access_token = get_access_token()
print(
requests.get(url_string, headers={'Authorization': f"Bearer {access_token}"}
)
如文档中所述,仅允许内部流量提到以下内容:
只允许来自同一项目或VPC服务控制周边的VPC网络的请求。所有其他请求都被拒绝。
请注意,由于App Engine Standard是一个无服务器产品,它不属于VPC,因此不考虑从该产品发出的请求;内部";调用,实际上这些调用是从实例的公共IP进行的,因此您会收到一条HTTP403错误消息。
同样,使用VPC无服务器连接器也不起作用,因为这更像是连接VPC中资源(如VM或内存存储实例(的桥梁,而不是云功能,因为这也是一个无服务器产品,并且在VPC中没有IP。
我认为有三种选择:
-
使用应用程序引擎Flex:
由于App Engine Flex使用VM实例,这些实例将是VPC的一部分,即使在设置";只允许内部流量";选项
-
使用虚拟机作为代理:
您可以创建一个VPC无服务器连接器,并将其分配给app Engine中的应用程序。然后,您可以创建一个虚拟机,并使用该虚拟机作为代理访问函数。由于成本原因,这不是最好的选择,但最终是一种选择。
-
最后一个选项认为该功能可以使用允许所有流量选项:
您可以在云功能上设置一些安全性,只允许特定的服务帐户,并且可以使用此示例代码进行身份验证。
编辑:
@gaefan在另一个答案中分享了这个选项的一个很好的代码示例。
@GAEfan是正确的。
作为补充:我使用了官方的Google Auth库,为我提供了必要的标题。
const {GoogleAuth} = require('google-auth-library');
// Instead of specifying the type of client you'd like to use (JWT, OAuth2, etc)
// this library will automatically choose the right client based on the environment.
const googleCloudFunctionURL = 'https://europe-west1-project.cloudfunctions.net/function';
(async function() {
const auth = new GoogleAuth();
let googleCloudFunctionClient = await auth.getIdTokenClient(googleCloudFunctionURL);
console.log(await googleCloudFunctionClient.getRequestHeaders(googleCloudFunctionURL));
})();