API Key 생성하기
API Gateway에 등록된 API를 사용하기 위해서 먼저 API Key를 생성해야 합니다.
① API Keys 메뉴를 선택합니다.
② API Key 생성을 클릭합니다.
① API Key 생성에 필요한 값을 입력합니다.
- 이름: API Key의 이름을 입력합니다.
- 설명: API Key의 설명을 입력합니다.
② 저장을 클릭합니다.
① 생성한 API Key를 조회할 수 있습니다.
- 상태: API Key가 활성화되어 있는지 나타냅니다. 비활성화된 API Key는 사용할 수 없습니다.
- Primary/Secondary Key: API를 호출할 때 Header에 넣어야 하는 값입니다. 이 값은 변경할 수 있습니다.
② 연결된 Stage 보기를 클릭하여 API Key가 사용하고 있는 API의 사용량을 볼 수 있습니다.
Product 구독하기
① Published APIs 메뉴로 이동하여 구독하고자 하는 상품을 선택합니다.
- Published APIs의 기본 필드는 NCP입니다.
- NCP에서 제공하는 API 이외의 다른 API 목록을 조회하시려면 필터를 변경해주세요.
② Catalog를 클릭합니다.
① 구독하기를 클릭합니다.
- 상품의 구독 타입이 공개 - 자율구독이라면 구독하기 버튼이 보이지 않습니다. 별도의 절차 없이 API를 호출할 수 있습니다.
- 상품의 구독 타입이 보호 - 승인필요라면 구독하기 버튼이 보입니다. API 호출을 위해 API Key 승인 절차가 필요합니다.
① 내가 소유한 API Key 목록을 확인할 수 있습니다.
② API Key를 선택하고 구독요청을 클릭하여 승인을 요청합니다.
API 호출하기
호출하려는 상품의 API Document를 참고하세요.
인증이 없는 API 호출하기
Header | Description |
---|---|
x-ncp-apigw-api-key | API Gateway에서 발급받은 키 (primary key 또는 secondary key) API Key를 요구하는 경우에만 추가 |
curl -i -X GET \
-H "x-ncp-apigw-api-key:cstWXuw4wqp1EfuqDwZeMz5fh0epaTykRRRuy5Ra" \
'https://uh7m0wgsis.apigw.ntruss.com/petStore/v1/pets'
IAM 인증이 필요한 API 호출하기
Header | Description |
---|---|
x-ncp-apigw-api-key | API Gateway에서 발급받은 키 (primary key 또는 secondary key) API Key를 요구하는 경우에만 추가 |
x-ncp-apigw-timestamp | 1970년 1월 1일 00:00:00 협정 세계시(UTC)부터의 경과 시간을 밀리초(millisecond)로 나타낸 것이다. APIGW 서버와 시간차가 5분 이상 나는 경우 유효하지 않은 요청으로 간주 |
x-ncp-iam-access-key | 포털 또는 sub account에서 발급받은 Access Key ID |
x-ncp-apigw-signature-v2 | Access Key Id와 맵핑되는 SecretKey로 암호화한 서명 HMAC 암호화 알고리즘은 HmacSHA256 사용 |
curl -i -X GET \
-H "x-ncp-apigw-timestamp:1505290625682" \
-H "x-ncp-apigw-api-key:cstWXuw4wqp1EfuqDwZeMz5fh0epaTykRRRuy5Ra" \
-H "x-ncp-iam-access-key:D78BB444D6D3C84CA38A" \
-H "x-ncp-apigw-signature-v2:WTPItrmMIfLUk/UyUIyoQbA/z5hq9o3G8eQMolUzTEo=" \
'https://uh7m0wgsis.apigw.ntruss.com/petStore/v1/pets'
Access Key ID, SecretKey 확인하기
IAM AccessKey 생성을 참고하세요.
Signature 생성하기
요청 | StringToSign |
---|---|
GET /photos/puppy.jpg?query1=&query2 x-ncp-apigw-timestamp={timestamp} x-ncp-apigw-api-key={apiKey} x-ncp-iam-access-key={accesskey} x-ncp-apigw-signature-v2={signature} |
GET /photos/puppy.jpg?query1=&query2 {timeStamp} {accessKey} |
서명에 사용되는 URL에는 도메인이 포함되지 않습니다. 개행문자는 \n을 사용합니다. 주의 : 요청 헤더의 x-ncp-apigw-timestamp 값과 StringToSign의 timestamp는 반드시 같은 값이여야 합니다.
요청에 맞게 StringToSign를 생성하고 SecretKey로 HmacSHA256 알고리즘으로 암호화한 후 Base64로 인코딩합니다.
이 값을 x-ncp-apigw-signature-v2
로 사용합니다.
- Java 샘플 코드
public String makeSignature() {
String space = " "; // one space
String newLine = "\n"; // new line
String method = "GET"; // method
String url = "/photos/puppy.jpg?query1=&query2"; // url (include query string)
String timestamp = "{timestamp}"; // current timestamp (epoch)
String accessKey = "{accessKey}" // access key id (from portal or sub account)
String secretKey = "{secretKey}";
String message = new StringBuilder()
.append(method)
.append(space)
.append(url)
.append(newLine)
.append(timestamp)
.append(newLine)
.append(accessKey)
.toString();
SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(message.getBytes("UTF-8"));
String encodeBase64String = Base64.encodeBase64String(rawHmac);
return encodeBase64String;
}
- Java script 샘플 코드
/*
https://code.google.com/archive/p/crypto-js/
https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/crypto-js/CryptoJS%20v3.1.2.zip
*/
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
<script type="text/javascript" src="./CryptoJS/rollups/hmac-sha256.js"></script>
<script type="text/javascript" src="./CryptoJS/components/enc-base64.js"></script>
function makeSignature() {
var space = " "; // one space
var newLine = "\n"; // new line
var method = "GET"; // method
var url = "/photos/puppy.jpg?query1=&query2"; // url (include query string)
var timestamp = "{timestamp}"; // current timestamp (epoch)
var accessKey = "{accessKey}" // access key id (from portal or sub account)
var secretKey = "{secretKey}"; // secret key (from portal or sub account)
var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, secretKey);
hmac.update(method);
hmac.update(space);
hmac.update(url);
hmac.update(newLine);
hmac.update(timestamp);
hmac.update(newLine);
hmac.update(accessKey);
var hash = hmac.finalize();
return hash.toString(CryptoJS.enc.Base64);
}
- Python 3 샘플 코드
import sys
import os
import hashlib
import hmac
import base64
import requests
import time
def make_signature():
timestamp = int(time.time() * 1000)
timestamp = str(timestamp)
access_key = "{accessKey}" # access key id (from portal or sub account)
secret_key = "{secretKey}" # secret key (from portal or sub account)
secret_key = bytes(secret_key, 'UTF-8')
method = "GET"
uri = "/photos/puppy.jpg?query1=&query2"
message = method + " " + uri + "\n" + timestamp + "\n" + access_key
message = bytes(message, 'UTF-8')
signingKey = base64.b64encode(hmac.new(secret_key, message, digestmod=hashlib.sha256).digest())
return signingKey
- Bash 샘플코드
function makeSignature() {
nl=$'\\n'
TIMESTAMP=$(echo $(($(date +%s%N)/1000000)))
ACCESSKEY="{accessKey}" # access key id (from portal or sub account)
SECRETKEY="{secretKey}" # secret key (from portal or sub account)
METHOD="GET"
URI="/photos/puppy.jpg?query1=&query2"
SIG="$METHOD"' '"$URI"${nl}
SIG+="$TIMESTAMP"${nl}
SIG+="$ACCESSKEY"
SIGNATURE=$(echo -n -e "$SIG"|iconv -t utf8 |openssl dgst -sha256 -hmac $SECRETKEY -binary|openssl enc -base64)
}
- Objective-C 샘플코드
#include <CommonCrypto/CommonDigest.h>
#include <CommonCrypto/CommonHMAC.h>
- (NSString*) makeSignature
{
NSString* space = @" ";
NSString* newLine = @"\n";
NSString* method = @"GET";
NSString* url = @"/photos/puppy.jpg?query1=&query2";
NSString* timestamp = @"{timestamp}"
NSString* accessKey = @"{accessKey}";
NSString* secretKey = @"{secretKey}";
NSString* message = [[NSString alloc] init];
message = [message stringByAppendingString:method];
message = [message stringByAppendingString:space];
message = [message stringByAppendingString:url];
message = [message stringByAppendingString:newLine];
message = [message stringByAppendingString:timestamp];
message = [message stringByAppendingString:newLine];
message = [message stringByAppendingString:accessKey];
const char *cKey = [secretKey cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [message StringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *hash = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
const uint8_t* input = (const uint8_t*)[hash bytes];
NSInteger length = [theData length];
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t* output = (uint8_t*)data.mutableBytes;
NSInteger i;
for (i=0; i < length; i += 3) {
NSInteger value = 0;
NSInteger j;
for (j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
NSInteger theIndex = (i / 3) * 4;
output[theIndex + 0] = table[(value >> 18) & 0x3F];
output[theIndex + 1] = table[(value >> 12) & 0x3F];
output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
}
return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
}
에러 코드
HttpStatusCode | ErrorCode | ErrorMessage | 설명 |
---|---|---|---|
400 | 100 | Bad Request Exception | protocol(https), endocing(UTF-8) 등 request 에러 |
401 | 200 | Authentication Failed | 인증 실패 |
401 | 210 | Permission Denied | 권한 없음 |
404 | 300 | Not Found Exception | Not found |
429 | 400 | Quota Exceeded | Quota 초과 |
429 | 410 | Throttle Limited | Rate 초과 |
429 | 420 | Rate Limited | Rate 초과 |
413 | 430 | Request Entity Too Large | 요청 엔티티 크기 초과 |
503 | 500 | Endpoint Error | 엔드포인트 연결 에러 |
504 | 510 | Endpoint Timeout | 엔드포인트 연결 시간 초과 |
500 | 900 | Unexpected Error | 예외 처리가 안된 에러 |
에러 응답 형식
요청 Content-Type이 application/xml일 때
<?xml version='1.0' encoding='UTF-8' ?> <Message> <error> <errorCode>210</errorCode> <message>Permission Denied</message> </error> </Message>
그외
{ "error":{ "errorCode":"210", "message":"Permission Denied" } }