인증 헤더 만들기
인증 헤더 만들기
Private API 요청 시 발급받은 Connect Key와 Secret Key를 이용하여 4개의 파라미터를 헤더에 추가하여 전송합니다.
요청 변수 | 설명 | 타입 |
---|---|---|
api-client-type | Api-Sign 생성 시 사용하는 구분자 유형 | String/선택 |
Api-Key | 사용자 API Key | String/필수 |
Api-Nonce | 현재의 시간을 밀리초(millisecond, ms)로 표현한 값 | String/필수 |
Api-Sign | End Point + Request Parameter + Api-Nonce + 사용자 Secret Key를 | String/필수 |
생성된 인증 헤더의 페이로드 예시입니다.
{
"api-client-type" : "2",
"Api-Sign" : "OGU1NWYxYjRmYmJjMzRmZWIyM2FkMGFkghhvbDGVSDgweY2ZkYzE2MzIwY2I2OGZlZmViOGY2OWE1MDFlZmNiZWMyNTBjOWY5NWRhMTQyZDdkOTFlNzQzZGUwNTM1MjJjMDdjNTEGgvdw2EyOTMwMzVkNzc=",
"Api-Nonce" : "1655282125050",
"Api-Key" : "3095809fgv90t4hnf82fls9023rlasf023nl"
}
Api-Sign 생성 안내
-
Request Parameter 조합
- endpoint 파라미터 추가
endpoint=/info/balance&order_currency=BTC&payment_currency=KRW
- URL 인코딩
endpoint=%2Finfo%2Fbalance&order_currency=BTC&payment_currency=KRW
- endpoint 파라미터 추가
-
End Point + Request Parameter + Api-Nonce 조합
- api-client-type에서 지정한 구분자를 이용해 3개의 값을 조합합니다.
/info/balance;endpoint=%2Finfo%2Fbalance&order_currency=BTC&payment_currency=KRW;1655283111604
- api-client-type에서 지정한 구분자를 이용해 3개의 값을 조합합니다.
-
HmacSha512 알고리즘으로 인코딩
- 2번에서 조합한 값을 사용자의 Secret Key를 이용하여 인코딩합니다.
-
Base64 인코딩
- HmacSha512로 인코딩한 값을 다시 Base64로 인코딩합니다.
private String usecTime() {
return String.valueOf(System.currentTimeMillis());
}
public static String encodeURIComponent(String s) {
String result = null;
try {
result = URLEncoder.encode(s, "UTF-8")
.replaceAll("\\+", "%20")
.replaceAll("\\%21", "!")
.replaceAll("\\%27", "'")
.replaceAll("\\%28", "(")
.replaceAll("\\%29", ")")
.replaceAll("\\%26", "&")
.replaceAll("\\%3D", "=")
.replaceAll("\\%7E", "~");
} catch (UnsupportedEncodingException e) {
result = s;
}
return result;
}
private static final String DEFAULT_ENCODING = "UTF-8";
private static final String HMAC_SHA512 = "HmacSHA512";
public static byte[] hmacSha512(String value, String key){
try {
SecretKeySpec keySpec = new SecretKeySpec(
key.getBytes(DEFAULT_ENCODING),
HMAC_SHA512);
Mac mac = Mac.getInstance(HMAC_SHA512);
mac.init(keySpec);
final byte[] macData = mac.doFinal( value.getBytes( ) );
byte[] hex = new Hex().encode( macData );
return hex;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (InvalidKeyException e) {
throw new RuntimeException(e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static String asHex(byte[] bytes){
return new String(Base64.encodeBase64(bytes));
}
private HashMap<String, String> getHttpHeaders(String endpoint, HashMap<String, String> rgData, String apiKey, String apiSecret) {
String strData = Util.mapToQueryString(rgData).replace("?", "");
String nNonce = usecTime();
strData = strData.substring(0, strData.length()-1);
strData = encodeURIComponent(strData);
HashMap<String, String> array = new HashMap<String, String>();
String str = endpoint + ";" + strData + ";" + nNonce;
String encoded = asHex(hmacSha512(str, apiSecret));
array.put("api-client-type", "2");
array.put("Api-Key", apiKey);
array.put("Api-Sign", encoded);
array.put("Api-Nonce", String.valueOf(nNonce));
return array;
}
def microtime(self, get_as_float = False):
if get_as_float:
return time.time()
else:
return '%f %d' % math.modf(time.time())
def usecTime(self) :
mt = self.microtime(False)
mt_array = mt.split(" ")[:2];
return mt_array[1] + mt_array[0][2:5];
def xcoinApiCall(self, endpoint, rgParams):
# 1. Api-Sign and Api-Nonce information generation.
# 2. Request related information from the Bithumb API server.
#
# - nonce: it is an arbitrary number that may only be used once.
# - api_sign: API signature information created in various combinations values.
endpoint_item_array = {
"endpoint" : endpoint
};
uri_array = dict(endpoint_item_array, **rgParams); # Concatenate the two arrays.
str_data = urllib.parse.urlencode(uri_array);
nonce = self.usecTime();
data = endpoint + chr(0) + str_data + chr(0) + nonce;
utf8_data = data.encode('utf-8');
key = self.api_secret;
utf8_key = key.encode('utf-8');
h = hmac.new(bytes(utf8_key), utf8_data, hashlib.sha512);
hex_output = h.hexdigest();
utf8_hex_output = hex_output.encode('utf-8');
api_sign = base64.b64encode(utf8_hex_output);
utf8_api_sign = api_sign.decode('utf-8');
curl_handle = pycurl.Curl();
curl_handle.setopt(pycurl.POST, 1);
#curl_handle.setopt(pycurl.VERBOSE, 1); # vervose mode :: 1 => True, 0 => False
curl_handle.setopt(pycurl.POSTFIELDS, str_data);
url = self.api_url + endpoint;
curl_handle.setopt(curl_handle.URL, url);
curl_handle.setopt(curl_handle.HTTPHEADER, ['Api-Key: ' + self.api_key, 'Api-Sign: ' + utf8_api_sign, 'Api-Nonce: ' + nonce]);
curl_handle.setopt(curl_handle.WRITEFUNCTION, self.body_callback);
curl_handle.perform();
#response_code = curl_handle.getinfo(pycurl.RESPONSE_CODE); # Get http response status code.
curl_handle.close();
return (json.loads(self.contents));
XCoinAPI.prototype._getHttpHeaders = function(endPoint, rgParams, api_key, api_secret) {
var strData = http_build_query(rgParams);
var nNonce = this.usecTime();
return {
'Api-Key' : api_key,
'Api-Sign' : (base64_encode(CryptoJS.HmacSHA512(endPoint + chr(0) + strData + chr(0) + nNonce, api_secret).toString())),
'Api-Nonce' : nNonce
};
}
XCoinAPI.prototype.usecTime = function(){
var rgMicrotime = microtime().split(' '),
usec = rgMicrotime[0],
sec = rgMicrotime[1];
usec = usec.substr(2, 3);
return Number(String(sec) + String(usec));
}
function microtime(get_as_float) {
var now = new Date()
.getTime() / 1000;
var s = parseInt(now, 10);
return (get_as_float) ? now : (Math.round((now - s) * 1000) / 1000) + ' ' + s;
}
function http_build_query(obj) {
var output_string = []
Object.keys(obj).forEach(function (val) {
var key = val;
key = encodeURIComponent(key.replace(/[!'()*]/g, escape));
if (typeof obj[val] === 'object') {
var query = build_query(obj[val], null, key)
output_string.push(query)
}
else {
var value = encodeURIComponent(obj[val].replace(/[!'()*]/g, escape));
output_string.push(key + '=' + value)
}
})
return output_string.join('&');
}
샘플 소스 전체 다운로드
Updated 12 days ago
Did this page help you?