Developer

문서 검색

엔드포인트, 개념, 에러 코드 검색

시작하기
소개/인증과 서명

인증과 서명

모든 프라이빗 요청은 Authorization 헤더에 JWT를 담아 보냅니다. 페이로드에는 Access Key, nonce, 쿼리 해시가 들어가고 Secret Key로 HMAC-SHA256 서명합니다.

JWT 페이로드

access_keystring

콘솔에서 발급한 Access Key.

nonceuuid

요청마다 유일한 값. 재사용 시 401.

timestampint64

밀리초 단위 시간. 서버와 ±30초 이내.

query_hashstring

쿼리 문자열의 SHA-512 해시. GET·POST 모두 필요.

query_hash_algstring

고정값 SHA512.

서버에서 서명하기

import crypto from "node:crypto";
import jwt from "jsonwebtoken";

function sign(query: string) {
  const hash = crypto.createHash("sha512").update(query).digest("hex");
  return jwt.sign(
    {
      access_key: process.env.INEX_ACCESS_KEY,
      nonce: crypto.randomUUID(),
      timestamp: Date.now(),
      query_hash: hash,
      query_hash_alg: "SHA512"
    },
    process.env.INEX_SECRET_KEY!
  );
}

export async function POST(req: Request) {
  const body = await req.json();
  const query = new URLSearchParams(body).toString();

  const res = await fetch("https://api.inexcoin.com/v1/orders", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${sign(query)}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify(body)
  });

  return Response.json(await res.json(), { status: res.status });
}
주의

nonce는 요청마다 유일해야 하며, 재사용하면 401 invalid_jwt_nonce가 반환됩니다. 토큰이 만료되면 401 expired_token이 반환되니 새 토큰을 발급해 재요청하세요.

언어별 예제

파라미터 없는 요청

쿼리 파라미터가 없는 GET 요청은 query_hash 없이 access_keynonce만으로 JWT를 구성합니다.

public class GetInexAccount {

  public static void main(String[] args) {
    final String accessKey = "발급 받은 access key";
    final String secretKey = "발급 받은 secret key";
    final String serverUrl = "https://api.inexcoin.com";

    Key key = Keys.hmacShaKeyFor(secretKey.getBytes());
    String jwtToken = Jwts.builder()
        .addClaims(Map.of("access_key", accessKey, "nonce", UUID.randomUUID().toString()))
        .signWith(key)
        .compact();

    try {
      HttpClient client = HttpClientBuilder.create().build();
      HttpGet request = new HttpGet(serverUrl + "/v1/tickers");
      request.setHeader("Content-Type", "application/json");
      request.addHeader("Authorization", String.format("%s %s", "Bearer", jwtToken));

      String responseString = client.execute(request, new BasicHttpClientResponseHandler());
      System.out.println("responseString = " + responseString);

    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

파라미터 있는 요청

쿼리 파라미터가 있는 요청은 쿼리 문자열을 SHA-512로 해싱해 query_hash, query_hash_alg를 JWT 페이로드에 추가해야 합니다.

public class GetInexAccount {

  public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
    final String accessKey = "발급 받은 access key";
    final String secretKey = "발급 받은 secret key";
    final String serverUrl = "https://api.inexcoin.com?market=BTC&userId=1";

    String queryString = "market=BTC&userId=1";

    MessageDigest md = MessageDigest.getInstance("SHA-512");
    md.update(queryString.getBytes("utf8"));

    String queryHash = String.format("%0128x", new BigInteger(1, md.digest()));

    Key key = Keys.hmacShaKeyFor(secretKey.getBytes());
    String jwtToken = Jwts.builder()
        .addClaims(Map.of("access_key", accessKey, "nonce", UUID.randomUUID().toString()
        , "query_hash", queryHash, "query_hash_alg", "SHA512"))
        .signWith(key)
        .compact();

    try {
      HttpClient client = HttpClientBuilder.create().build();
      HttpGet request = new HttpGet(serverUrl);
      request.setHeader("Content-Type", "application/json");
      request.addHeader("Authorization", String.format("%s %s", "Bearer", jwtToken));

      String responseString = client.execute(request, new BasicHttpClientResponseHandler());
      System.out.println("responseString = " + responseString);

    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}