使用App Scripts调用Gemini API时持续出现InvalidSignature错误求助
Gemini API调用出现InvalidSignature错误的排查与修复
问题描述
我尝试使用App Scripts调用Gemini API,但始终收到InvalidSignature错误提示。所用代码是根据Gemini官方文档中的Python代码转换而来的私有API调用实现。
原代码
function createHeaders(payload) { var geminiApiKey = API_KEY var geminiApiSecret = SECRET_KEY var encodedApiSecret = Utilities.newBlob(geminiApiSecret, 'UTF-8').getBytes() var payloadNonce = new Date().getTime() / 1000; payload["nonce"] = Math.round(payloadNonce); var encodedPayload = Utilities.newBlob(JSON.stringify(payload), 'UTF-8').getBytes() var b64 = Utilities.base64Encode(encodedPayload) //string var signature = Utilities.computeHmacSignature( Utilities.MacAlgorithm.HMAC_SHA_384, b64, geminiApiKeyAuditor ) //bytes return { "Content-Type": "text/plain", "X-GEMINI-APIKEY": geminiApiKeyAuditor, "X-GEMINI-PAYLOAD": b64, "X-GEMINI-SIGNATURE": Utilities.base64Encode(signature), //string "Cache-Control": "no-cache" }; } function fetchGeminiData() { var baseUrl = "https://api.gemini.com"; var url = baseUrl + "/v1/mytrades"; var payload = { "request": "/v1/mytrades" }; var headers = createHeaders(payload); var options = { "method": "post", "headers": headers, }; var response = UrlFetchApp.fetch(url, options); var responseData = response.getContentText(); var jsonResponse = JSON.parse(responseData); Logger.log(jsonResponse); }
错误信息
Exception: Request failed for https://api.gemini.com returned code 400. Truncated server response: {"result":"error","reason":"InvalidSignature","message":"InvalidSignature"}
问题排查与修复
1. 变量名错误(核心问题)
代码中多处使用了未定义的geminiApiKeyAuditor,这是导致签名验证失败的主要原因:
- 计算HMAC签名时,第三个参数应该是API密钥的字节数组(
encodedApiSecret),而非错误的geminiApiKeyAuditor - 请求头中的
X-GEMINI-APIKEY应该是你的实际API密钥(geminiApiKey),而非geminiApiKeyAuditor
2. Nonce唯一性问题
原代码中对时间戳除以1000后取整,可能导致短时间内请求的nonce重复,触发签名验证失败。建议直接使用毫秒级时间戳作为nonce,确保每次请求的nonce唯一:
payload["nonce"] = new Date().getTime();
3. 修复后的完整代码
function createHeaders(payload) { var geminiApiKey = API_KEY; // 确保已正确定义你的API密钥 var geminiApiSecret = SECRET_KEY; // 确保已正确定义你的密钥 var encodedApiSecret = Utilities.newBlob(geminiApiSecret, 'UTF-8').getBytes(); // 使用毫秒级时间戳作为nonce,保证唯一性 payload["nonce"] = new Date().getTime(); var encodedPayload = Utilities.newBlob(JSON.stringify(payload), 'UTF-8').getBytes(); var b64 = Utilities.base64Encode(encodedPayload); var signature = Utilities.computeHmacSignature( Utilities.MacAlgorithm.HMAC_SHA_384, b64, encodedApiSecret ); return { "Content-Type": "text/plain", "X-GEMINI-APIKEY": geminiApiKey, "X-GEMINI-PAYLOAD": b64, "X-GEMINI-SIGNATURE": Utilities.base64Encode(signature), "Cache-Control": "no-cache" }; } function fetchGeminiData() { var baseUrl = "https://api.gemini.com"; var url = baseUrl + "/v1/mytrades"; var payload = { "request": "/v1/mytrades" }; var headers = createHeaders(payload); var options = { "method": "post", "headers": headers, "muteHttpExceptions": true // 可选,便于查看完整错误响应内容 }; var response = UrlFetchApp.fetch(url, options); var responseData = response.getContentText(); var jsonResponse = JSON.parse(responseData); Logger.log(jsonResponse); }
内容的提问来源于stack exchange,提问作者Koh
相关产品推荐
相关产品推荐

