如何在Firebase Cloud Function中获取调用Firebase Hosting API的访问令牌?
在Firebase云函数中安全获取Hosting API访问令牌的方案
第一步:配置服务账号权限
云函数默认使用的服务账号(格式一般是[你的项目ID]@appspot.gserviceaccount.com)必须拥有Firebase Hosting的操作权限,否则拿到令牌也无法调用API。前往Google Cloud控制台的IAM与管理员页面,给该账号添加Firebase Hosting Admin角色;如果只需部署权限,也可添加更细粒度的权限,比如firebasehosting.releases.create和firebasehosting.sites.update。
第二步:通过元数据服务器获取临时令牌
Firebase云函数运行在GCP环境中,可直接通过内置的元数据服务器获取临时访问令牌,全程无需存储服务账号密钥,这是安全合规的解决方案。以下是Node.js实现代码:
安装依赖(按需)
如果你的云函数使用Node.js版本低于18(无内置fetch),先安装node-fetch:
npm install node-fetch
云函数代码示例
const functions = require('firebase-functions'); const fetch = require('node-fetch'); // Node.js 18+可直接用globalThis.fetch,无需安装 // 封装获取Hosting访问令牌的函数 async function getHostingAccessToken() { const metadataEndpoint = 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token'; const res = await fetch(metadataEndpoint, { headers: { 'Metadata-Flavor': 'Google' // 必须添加该请求头,否则元数据服务器会拒绝访问 } }); if (!res.ok) { throw new Error(`令牌获取失败:${res.statusText}`); } const tokenData = await res.json(); // tokenData.access_token即为可用令牌,有效期约1小时,无需手动刷新,每次调用前重新获取即可 return tokenData.access_token; } // 示例:当Firestore新增用户内容时,自动部署到Hosting exports.deployUserGeneratedContent = functions.firestore.document('user-content/{contentId}') .onCreate(async (snapshot) => { // 1. 从Firestore拉取数据并生成静态内容(此部分逻辑需根据你的业务实现) const userContent = snapshot.data(); const staticHtml = `<html><h1>${userContent.title}</h1><p>${userContent.content}</p></html>`; // 2. 获取Hosting API访问令牌 const accessToken = await getHostingAccessToken(); // 3. 调用Firebase Hosting API上传静态内容 const hostingSiteName = '你的Hosting站点名称'; // 在Firebase控制台Hosting页面可查看 const uploadUrl = `https://firebasehosting.googleapis.com/v1beta1/sites/${hostingSiteName}/uploads`; const uploadRes = await fetch(uploadUrl, { method: 'POST', headers: { 'Authorization': `Bearer ${accessToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ files: [ { path: `/user-pages/${userContent.slug}.html`, // 内容部署到Hosting的路径 content: Buffer.from(staticHtml).toString('base64') // 内容需转为base64格式 } ] }) }); if (!uploadRes.ok) { const errorMsg = await uploadRes.text(); throw new Error(`部署失败:${errorMsg}`); } console.log('用户生成内容已成功部署到Firebase Hosting'); });
关键注意事项
- 元数据服务器仅在GCP内部环境(包括Firebase云函数)可访问,本地测试时可使用
gcloud auth application-default print-access-token命令生成临时令牌替代。 - 令牌有效期为1小时,无需手动刷新,每次调用API前重新获取即可避免过期问题。
- 若调用API时提示权限不足,需回到Google Cloud IAM页面检查服务账号的权限配置是否正确。
内容的提问来源于stack exchange,提问作者Amy
相关产品推荐
相关产品推荐

