TheKoguryo's 기술 블로그

Version 2019.06.03

14.3.4 Postman - OCI REST API 호출하기

Postman - OCI REST API 호출하기

가장 많이 사용하는 전문 REST 클라이언트 툴인 Postman을 사용하면 GUI를 통해 사용하기가 더 편리합니다. 아직 OCI Request Signature를 기본 지원하지 않아, Postman의 pre-script를 사용하여 OCI REST API를 호출하는 방법을 설명하고자 합니다.

OCI Request Signature를 통한 호출을 하기 위해 Postman에서는 pre-script를 사용해야 합니다. Insomina처럼 플러그인 기능은 제공하지 않습니다. pre-script는 REST 요청단위로 설정할 수 있고, 폴더, Collection 단위로도 설정할 수 있습니다.

폴더에 pre-script를 설정하면, 폴더하위의 모든 REST 요청전에 pre-script가 먼저 실행됩니다. 관리 편의를 위해 폴더의 pre-script를 사용하겠습니다.

Step 1. pre-script에서 쓸 RSA 라이브러리 로딩

※ 외부 RSA 자바스크립트 라이브러리 로딩 pre-script에서 기본 포함된 Cryto 라이브러리는 OCI Request Signature가 사용하는 RSA 암호화를 지원하지 않습니다. 그래서 다음방식으로 우회하여 외부 암호화 라이브러리를 추가합니다.

  1. GET 요청 만들기

  2. Test 탭에 다음 복사

    pm.globals.set("jsrsasign-js", responseBody);
  3. 요청 실행

  4. 실행결과
    아래와 같이 실행되면 암호화모듈이 Postman 글로벌 변수(jsrsasign-js)에 저장됩니다.
    그림

Step 2. pre-script 설정

  1. REST 요청을 포함할 폴더를 생성합니다.

  2. 폴더 이름을 우클릭 하고 Edit 클릭
    그림

  3. 폴더 설정에서 Pre-request Scripts 탭을 선택합니다.
    그림

  4. 다음 자바스크립트을 복사해서 붙여넣습니다.

var navigator = {}; //fake a navigator object for the lib
var window = {}; //fake a window object for the lib
eval(pm.globals.get("jsrsasign-js")); //import javascript jsrsasign

const isOracleCloud = pm.environment.get("isOracleCloud");

if (isOracleCloud != "true")
  return;

const tenancyId = pm.environment.get('tenancyId');
const authUserId = pm.environment.get('authUserId');
const keyFingerprint = pm.environment.get('keyFingerprint');

var privateKey = pm.environment.get("privateKey");

var signAlgorithm = "RSA-SHA256";
var sigVersion = "1";
var now = new Date().toUTCString();
var host = getHost(request.url.trim());
var target = getTarget(request.url.trim());
var method = request.method;
var keyId = tenancyId + "/" + authUserId + "/" + keyFingerprint;

var headers = "(request-target) date host";
var request_target="(request-target): " + method.toLowerCase() + " "  + target;
var date_header = "date: " + now;
var host_header = "host: " + host;

var signing_string = request_target + "\n" + date_header + "\n" + host_header;

var methodsThatRequireExtraHeaders = ["POST", "PUT"];

if(methodsThatRequireExtraHeaders.indexOf(method.toUpperCase()) !== -1) {
  var body = request.data;
  console.log(body);
  
  var signatureSign = CryptoJS.SHA256(body);
  var content_sha256 = signatureSign.toString(CryptoJS.enc.Base64);

  var content_type = "application/json";
  var content_length = body.length;

  headers = headers + " x-content-sha256 content-type content-length";
  var content_sha256_header = "x-content-sha256: " + content_sha256;
  var content_type_header = "content-type: " + content_type;
  var content_length_header = "content-length: " + content_length;

  signing_string = signing_string + "\n" + content_sha256_header + "\n" + content_type_header + "\n" + content_length_header;

  pm.environment.set("x-content-sha256_header", content_sha256);

}

// RSA signature generation
var signatureSign = new KJUR.crypto.Signature({"alg": "SHA256withRSA"});
signatureSign.init(privateKey);
signatureSign.updateString(signing_string);
var signedSignatureHex = signatureSign.sign();

var signedSignature = hexToBase64(signedSignatureHex);

const authorization = `Signature version="${sigVersion}", keyId="${keyId}", algorithm="${signAlgorithm.toLowerCase()}", headers="${headers}", signature="${signedSignature}"`;

pm.environment.set("date_header", now);
pm.environment.set("Authorization_header", authorization);

function getHost(url) {
  // https://identity.us-ashburn-1.oraclecloud.com/20160918/users/
  var n1 = url.indexOf("//");
  var n2 = url.indexOf("/", n1 + 2);

  var start = n1 + 2;
  var length = n2 - start;

  var host = url.substr(start, length);

  return host;
}

function getTarget(url) {
  // https://identity.us-ashburn-1.oraclecloud.com/20160918/users/
  
  url = url.replace(new RegExp('^https?://[^/]+/'),'/'); // strip hostname

  return url;
}

function hexToBase64(hexstring) {
    return btoa(hexstring.match(/\w{2}/g).map(function(a) {
        return String.fromCharCode(parseInt(a, 16));
    }).join(""));
}

Step 3. 환경변수 설정

  1. 필요 환경 변수
    • isOracleCloud: “true”로 설정, 설정한 플러그인인 글로벌하게 적용되는 것이라, true일때만 세부 스크립트가 동작함
    • tenancyId: tenancy OCID
    • authUserId: 사용자 OCID
    • keyFingerprint: API Key의 핑거프린트
    • privateKey: API Key로 등록한 Public Key에 매칭되는 Private Key의 텍스트를 그대로 복사해 붙입니다.
      그림

Step 4. 사용자 조회 REST API 실행

  1. REST 요청을 앞서 만든 폴더 밑으로 만듭니다.

  2. 오른쪽 위에 설정한 환경변수를 선택합니다.

  3. REST 요청의 Header에 그림과 같이 date, Authorization을 추가합니다.

    • date : {{date_header}}
    • Authorization : {{Authorization_header}}
    • date, Authorization의 실제 값은 pre-script가 실행되면서 실행시점에 설정됩니다.
    • POST, PUT을 제외한 HTTP Operation은 위 두 개만 설정합니다.
  4. 실행결과 그림

Step 5. 사용자 생성 REST API 실행

  1. REST 요청을 앞서 만든 폴더 밑으로 만듭니다.

  2. 오른쪽 위에 설정한 환경변수를 선택합니다.

  3. REST 요청의 Header에 그림과 같이 date, Authorization을 추가합니다.

    • date : {{date_header}}
    • Authorization : {{Authorization_header}}
    • Content-Type : application/json
    • x-content-sha256 : {{x-content-sha256_header}}
    • Content-Type을 제외한 세 개의 실제 값은 pre-script가 실행되면서 실행시점에 설정됩니다.
    • POST, PUT은 위 네 개를 설정합니다. 요청 메시지가 있어 요청메시지도 서명에 추가되기 때문입니다.
  4. 실행결과 그림

  5. POST, PUT으로 요청하는 경우 위 REST 요청을 복사해서 씁니다.

참고 문서

Postman의 pre-script에서 외부 RSA 자바스크립트 라이브러리를 사용하는 부분은 다음 링크를 참고하였습니다.



** 이 글은 개인으로서, 개인의 시간을 할애하여 작성된 글입니다. 글의 내용에 오류가 있을 수 있으며, 글 속의 의견은 개인적인 의견입니다. **
Last updated on 19 May 2019