Google Apps Script로 Coinbase Pro API 호출에 서명

Aug 25 2020

Google Apps Script를 사용하여 Coinbase Pro에 첫 번째 API 호출을 보내려고하는데 화가납니다. 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;
}
  • 이 경우 valuekeyof 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);  

}