从 Cloud Function 调用 Cloud 运行:IAM 身份验证
Call Cloud Run from Cloud Function: IAM Authentication
我已经通过 Google 云 运行 部署了一个小型 HTTP 端点。当我关闭身份验证时它工作正常。
我现在想打开它,以便它只能由我的 Firebase 云函数调用。如果我理解正确,我只需在 Cloud 运行 的 IAM 设置中添加正确的服务帐户邮件地址作为“Cloud 运行 invoker”。
但是哪个地址是正确的?
我已经尝试了在 Firebase 控制台 -> 项目设置 -> 服务帐户中找到的所有地址。
我想你可以查看具体的firebase函数。在UI中,应列出使用的服务帐户。
默认情况下,GCF函数全部使用@appspot.gserviceaccount.com
感谢@AhmetB - Google 和@whlee 的回答,我让它工作了。基本上,向请求添加一个授权承载令牌就足够了,您可以从一个特殊的端点获得:https://cloud.google.com/run/docs/authenticating/service-to-service#nodejs
然后您只需将函数的服务帐户添加到 Cloud 运行 容器的 IAM 列表中:@appspot.gserviceaccount.com
nodejs 示例使用已弃用的请求库,所以这是我使用 axios 的版本:
const getOAuthToken = async (receivingServiceURL: string): Promise<string> => {
// Set up metadata server request
const metadataServerTokenURL = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=';
const uri = metadataServerTokenURL + receivingServiceURL;
const options = {
headers: {
'Metadata-Flavor': 'Google'
}
};
return axios.get(uri, options)
.then((res) => res.data)
.catch((error) => Promise.reject(error));
}
那你就可以直接在实际请求中使用token了:
const url = `...`;
const token = await getOAuthToken(url);
axios.post(url, formData, {
headers: {
Authorization: `Bearer ${token}`,
}
}).then(...).catch(...);
@luhu 的回答很有帮助。对于那些愿意先在本地使用 模拟器进行测试的人 ,我想补充一点。元数据服务器(现在实际上是 http://metadata.google.internal
)正如他们所说的那样
does not work outside of Google Cloud, including from your local machine.
作为变通方法,您可以使用 google-auth-library
,如果您更喜欢坚持使用 axios,则可以直接获取令牌。请记住首先将 GOOGLE_APPLICATION_CREDENTIALS
env 变量设置为指向 service account 秘密,因为这是使其工作的唯一方法(我已经测试过在 admin.initializeApp()
期间设置 credential
字段但是好像不太喜欢)。
const {GoogleAuth} = require('google-auth-library');
const auth = new GoogleAuth();
const url_origin = '....'
const client = await auth.getIdTokenClient(url_origin);
const token = (await client.getRequestHeaders()).Authorization;
const url = '....'
const response = await axios.get(
url,
{
headers: {
Authorization: token,
},
}
);
我已经通过 Google 云 运行 部署了一个小型 HTTP 端点。当我关闭身份验证时它工作正常。
我现在想打开它,以便它只能由我的 Firebase 云函数调用。如果我理解正确,我只需在 Cloud 运行 的 IAM 设置中添加正确的服务帐户邮件地址作为“Cloud 运行 invoker”。 但是哪个地址是正确的?
我已经尝试了在 Firebase 控制台 -> 项目设置 -> 服务帐户中找到的所有地址。
我想你可以查看具体的firebase函数。在UI中,应列出使用的服务帐户。
默认情况下,GCF函数全部使用
感谢@AhmetB - Google 和@whlee 的回答,我让它工作了。基本上,向请求添加一个授权承载令牌就足够了,您可以从一个特殊的端点获得:https://cloud.google.com/run/docs/authenticating/service-to-service#nodejs
然后您只需将函数的服务帐户添加到 Cloud 运行 容器的 IAM 列表中:
nodejs 示例使用已弃用的请求库,所以这是我使用 axios 的版本:
const getOAuthToken = async (receivingServiceURL: string): Promise<string> => {
// Set up metadata server request
const metadataServerTokenURL = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=';
const uri = metadataServerTokenURL + receivingServiceURL;
const options = {
headers: {
'Metadata-Flavor': 'Google'
}
};
return axios.get(uri, options)
.then((res) => res.data)
.catch((error) => Promise.reject(error));
}
那你就可以直接在实际请求中使用token了:
const url = `...`;
const token = await getOAuthToken(url);
axios.post(url, formData, {
headers: {
Authorization: `Bearer ${token}`,
}
}).then(...).catch(...);
@luhu 的回答很有帮助。对于那些愿意先在本地使用 模拟器进行测试的人 ,我想补充一点。元数据服务器(现在实际上是 http://metadata.google.internal
)正如他们所说的那样
does not work outside of Google Cloud, including from your local machine.
作为变通方法,您可以使用 google-auth-library
,如果您更喜欢坚持使用 axios,则可以直接获取令牌。请记住首先将 GOOGLE_APPLICATION_CREDENTIALS
env 变量设置为指向 service account 秘密,因为这是使其工作的唯一方法(我已经测试过在 admin.initializeApp()
期间设置 credential
字段但是好像不太喜欢)。
const {GoogleAuth} = require('google-auth-library');
const auth = new GoogleAuth();
const url_origin = '....'
const client = await auth.getIdTokenClient(url_origin);
const token = (await client.getRequestHeaders()).Authorization;
const url = '....'
const response = await axios.get(
url,
{
headers: {
Authorization: token,
},
}
);