调用GCloud Storage触发SigningError:缺少client_email问题求助
问题场景
已配置包含正确client_email的服务账号JSON文件,环境变量GOOGLE_IAM_SERVICE_ACCOUNT_KEYFILE指向该文件,且账号拥有Storage Admin角色,但调用getFiles接口获取GCloud Storage文件时,仍抛出以下错误:
Caused by SigningError: Cannot sign data without `client_email`. at GoogleAuth.sign (/Users/User/app-firebase/functions/node_modules/@google-cloud/common/node_modules/google-auth-library/build/src/auth/googleauth.js:648:19) at sign (/Users/User/app-firebase/functions/node_modules/@google-cloud/storage/build/src/signer.js:91:35) From previous event: at File.wrapper (/Users/User/app-firebase/functions/node_modules/@google-cloud/promisify/build/src/index.js:42:16) at _callee$ (webpack-internal:///./src/api/utils/StorageUtils.ts:219:81)
用户使用的代码片段:
const storage = new Storage({ projectId: projectId, keyFilename: process.env.GOOGLE_IAM_SERVICE_ACCOUNT_KEYFILE, // correct path to service account json file }); console.log(storage); const [files] = await storage.bucket(bucketName).getFiles({ prefix, });
环境详情:
- OS: macOS 12.4
- Node version: 16.15.0
- npm version: 8.5.5
- @google-cloud/storage version: 5.3.0
解决方案
验证服务账号JSON完整性
打开JSON文件,确认client_email字段存在且值正确。完整的服务账号JSON应包含如下结构:{ "type": "service_account", "project_id": "your-project-id", "private_key_id": "xxx", "private_key": "xxx", "client_email": "your-service-account@your-project.iam.gserviceaccount.com", "client_id": "xxx", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "xxx" }若字段缺失或损坏,重新下载服务账号JSON文件。
确认环境变量路径有效性
在初始化Storage前添加日志,验证环境变量是否正确加载、文件路径是否存在:const fs = require('fs'); console.log('Key file path:', process.env.GOOGLE_IAM_SERVICE_ACCOUNT_KEYFILE); console.log('File exists:', fs.existsSync(process.env.GOOGLE_IAM_SERVICE_ACCOUNT_KEYFILE));本地运行时需确保
.env文件(若使用)已通过dotenv加载;Firebase Functions环境需确认变量已通过firebase functions:config:set配置。直接传入服务账号凭证内容
避免路径解析问题,直接读取JSON文件内容并传入credentials参数:const fs = require('fs'); const credentials = JSON.parse(fs.readFileSync(process.env.GOOGLE_IAM_SERVICE_ACCOUNT_KEYFILE, 'utf8')); const storage = new Storage({ projectId: projectId, credentials: credentials });修复依赖版本冲突
当前@google-cloud/storage@5.3.0版本较旧,可能存在依赖冲突。尝试更新到最新稳定版或重新安装依赖:# 更新包 npm install @google-cloud/storage@latest # 清理并重装依赖 rm -rf node_modules package-lock.json npm install检查Firebase Functions运行权限
若在Firebase Functions中运行,除自定义服务账号外,还需确认Functions默认运行账号([project-id]@appspot.gserviceaccount.com)是否拥有Storage访问权限,或确保代码中正确指定了自定义服务账号。
内容的提问来源于stack exchange,提问作者Dzsonah

