ลงนามการโทรไปยัง Coinbase Pro API ด้วย Google Apps Script

Aug 25 2020

ฉันจะบ้าพยายามส่งการเรียก API ครั้งแรกไปยัง Coinbase Pro โดยใช้ Google Apps Script ใน node.js นั้นค่อนข้างง่าย (https://docs.pro.coinbase.com/#signing-a-message) แต่การทำเช่นเดียวกันกับสคริปต์ของ Google เป็นการกลับมา "ลายเซ็นไม่ถูกต้อง" ซ้ำแล้วซ้ำเล่า

นี่คือรหัสที่ฉันใช้:

function GetMyAccounts () {
  var globalvars_CB = {
   'apikey'     : 'f7d20a*******18c',
   'secret'     : '******pIIitRbWCv9N/mMWaR*****mGQMuI+m/vSbU1zuh5U6WFiFw==',
   'passphrase' : 'ceacdsewfcsa',
   'uri'        : 'https://api.pro.coinbase.com'
  }
  
  var requestPath = '/accounts';
  
  var timestamp = Math.floor(Date.now() / 1000);

  var options = {
    'method' : 'GET',
    'muteHttpExceptions' : true,     
    'headers' : {
      'Content-Type': 'application/json',
      'CB-ACCESS-KEY' : globalvars_CB.apikey,
      'CB-ACCESS-SIGN' : SignAPICall(globalvars_CB.secret, timestamp, 'GET', requestPath, ''),
      'CB-ACCESS-TIMESTAMP' : timestamp,
      'CB-ACCESS-PASSPHRASE' :  globalvars_CB.passphrase,
          }
  }  
    
  var responseJson = UrlFetchApp.fetch(globalvars_CB.uri+requestPath, options);
  
  Logger.log(responseJson);
 }
    

function SignAPICall(secret, timestamp, method, requestPath, body) {

  var what = (timestamp + method + requestPath + body);
  
  var decodedsecret = Utilities.base64Decode(secret).toString();
  
  var hmac = Utilities.computeHmacSha256Signature(what, decodedsecret);
 
  hmac = Utilities.base64Encode(hmac);
  
  return (hmac);    

}

ฉันต้องการความช่วยเหลือจริงๆ :-) - ขอบคุณ!

คำตอบ

1 Tanaike Aug 25 2020 at 22:26

ในสคริปต์ของคุณสมมติว่าส่วนหัวคำขอของคุณยกเว้นค่าCB-ACCESS-SIGNและจุดสิ้นสุดถูกต้อง โปรดระวังสิ่งนี้

จุดปรับเปลี่ยน:

  • ในกรณีของUtilities.base64Decode(secret).toString()อาร์เรย์จะถูกแปลงเป็นสตริง ฉันคิดว่านี่อาจเป็นสาเหตุของปัญหาของคุณ

เมื่อจุดเหนือสะท้อนจะกลายเป็นดังนี้

สคริปต์ที่แก้ไข:

ในกรณีนี้ฟังก์ชันSignAPICallจะถูกแก้ไข

function SignAPICall(secret, timestamp, method, requestPath, body) {
  var what = (timestamp + method + requestPath + body);
  var decodedsecret = Utilities.base64Decode(secret);  // Modified
  var res = Utilities.computeHmacSha256Signature(Utilities.newBlob(what).getBytes(), decodedsecret);  // Modified
  hmac = Utilities.base64Encode(res);
  return hmac;
}
  • ในกรณีนี้valueและkeyของcomputeHmacSha256Signature(value, key)คืออาร์เรย์ไบต์

บันทึก:

  • เมื่อฉันตรวจสอบสคริปต์ที่แก้ไขด้านบนโดยเปรียบเทียบสคริปต์ตัวอย่างของเอกสารอย่างเป็นทางการฉันสามารถยืนยันได้ว่าสามารถรับผลลัพธ์เดียวกันได้
  • ขออภัยฉันไม่สามารถทดสอบคำขอไปยัง API โดยใช้สคริปต์ที่แก้ไขด้านบนได้ในขณะที่ฉันสามารถยืนยันได้ว่ามีการดึงลายเซ็นเดียวกันจากสคริปต์ตัวอย่างในเอกสารทางการจากสคริปต์ที่แก้ไขด้านบน ดังนั้นโปรดทดสอบคำขอในสภาพแวดล้อมของคุณ เมื่อคุณร้องขอไปยัง API โดยใช้สคริปต์ที่แก้ไขข้างต้นเมื่อเกิดข้อผิดพลาดโปรดตรวจสอบส่วนหัวของคำขอปลายทางและข้อมูลลับอีกครั้ง

อ้างอิง:

  • การลงนามในข้อความ
  • base64Decode (เข้ารหัส)
  • computeHmacSha256Signature (ค่า, คีย์)
AlbertSampietro Sep 06 2020 at 06:56

ในที่สุดฉันก็พบวิธีแก้ปัญหา มันเป็นปัญหากับประเภทของข้อมูลที่ฉันส่งไปที่ "Utilities.computeHmacSha256Signature" ในโค้ดคุณจะพบว่าฟังก์ชันทำงานได้ดี

function SignAndCallAPI(method, requestPath, body) {

  var timestamp = Math.floor(Date.now() / 1000).toString();
  
  var what = Utilities.base64Decode(Utilities.base64Encode(timestamp + method + requestPath + body));
  
  var decodedsecret = Utilities.base64Decode(globalvars_CB.secret);
  
  var hmac = Utilities.base64Encode(Utilities.computeHmacSha256Signature(what, decodedsecret));
     
  var options = {
    'method' : method,
    'muteHttpExceptions' : true,     
    'headers' : {
      'Content-Type': 'application/json',
      'CB-ACCESS-KEY' : globalvars_CB.apikey,
      'CB-ACCESS-SIGN' : hmac,
      'CB-ACCESS-TIMESTAMP' : timestamp,
      'CB-ACCESS-PASSPHRASE' :  globalvars_CB.passphrase,
     }
  }  
      
   var responseJson = UrlFetchApp.fetch(globalvars_CB.uri+requestPath, options);
  
  Logger.log(responseJson);
  return(responseJson);  

}