검색

레이블이 REST인 게시물을 표시합니다. 모든 게시물 표시
레이블이 REST인 게시물을 표시합니다. 모든 게시물 표시

2020년 7월 26일

JWT ( JSON WEB TOKEN ) 인증환경에서 이미지 다운로드

서버 세션이 아닌 JWT 토큰을 기반으로 하는 웹 프로그램은 서버와의 통신이 필요하면 HTTP 헤더에 JWT 토큰을 포함하여  요청하고 서버는 클라이언트 요청 헤더의  JWT 토큰을 꺼내어 인증 정보를 꺼네어 사용하게 된다. 이미지의 경우는 어떻까 ? 

HTML 에서 img  태그는 JWT 와 같은 보안 토큰을 헤더에 포함하는 기능을 제공하지 않는다. 그러나 이미지 데이터를 스크립트에서 다운로드하고  data : image / FILETYPE; base64 URI 체계를 사용하여 이미지를 웹 페이지에 포함시키는 방법을 사용하면 간단하게 제한을 극복할 수 있다. ( vue-auth-image 모듈이나 관련 글들을 참고하는 것이 많은 도움이 되었다.) 



다수의 이미지를 다운로드 하는 경우 요청간 지연을 주기 위하여 아래와 같은 방법을 사용했다.
  var delay = 600 ;
  $("#grid figure img[is-secure]").each(function () {
    var $this = $(this);
    delay = delay + 50 ;
    $this.parent().addClass('is-loading');
    studio.ui.setSecureImage($this, delay);
  });
  
이미지를 가져오지 못하는 경우에는 재요청을 수행하도록 코드하였다.
  
  function setSecureImage(elemment, delay, callback) {
  var delay = delay || 1000;
  let url = elemment.attr("secure-image");
  setImageAsBase64(
    url,
    function (data) {
      elemment.attr("src", data);
      elemment.parent().removeClass("is-loading");
      if (isFunction(callback)) callback();
    },
    function () {
      let maxRetry = 3,
        retry = 0;
      if (defined(elemment.data("max-retry"))) {
        maxRetry = elemment.data("max-retry");
      }
      if (defined(elemment.data("retry"))) {
        retry = elemment.data("retry");
      }
      if (retry < maxRetry) {
        elemment.data("retry", retry + 1);
        sleep(delay);
        setSecureImage(elemment);
      } else {
        elemment.parent().removeClass("is-loading");
      }
    }
  );
  }

  async function setImageAsBase64(url, successHandler, errorHandler) {
  const headers = {};
  // JWT 토큰 값 설정
  Object.assign(headers, studio.services.accounts.authHeader()); 
  await axios
    .get(url, { headers: headers, responseType: "arraybuffer" })
    .then((response) => {
      var mineType = response.headers["content-type"].toLowerCase();
      var b64encoded = Buffer.from(response.data, "binary").toString("base64");
      var prefix = "data:" + mineType + ";base64,";
      if (isFunction(successHandler)) successHandler(prefix + b64encoded);
    })
    .then((error) => {
      if (isFunction(errorHandler)) errorHandler();
    });
  } 
  



아쉽지만 이미지를 다운로드하여 data 방식으로 설정하는데 있어 오류가 발생되어 다시 시도하도록 추가한 코드는 효용성이 없는 것 같다. 테스트 환경 이슈일 수도 있으나 다운로드에 있어 무작위로 오류가 발생하며 일단 오류가 발생되면 다시 시도한 경우 역시 오류가 발생한다. (→ 서버 이슈인지 코드 이슈인지는 확실하지 않다.)

참고자료

2017년 10월 23일

Postman 을 이용한 REST API 개발 & 테스트

이제는 HTTP 를 기반으로하는 REST API 개발은 아주 일상적인 일이 되었다.

웹 기반의 RESR API 를 손쉽게 개발 & 테스트하는 도구로는 Postman 소프트웨어가 있다. (대부분의 모바일 개발자들은 다 알고 있을 것 같다)

Postman 은 www.getpostman.com 또는 크롬 웹 스토어 에서 설치할 수 있다.


먼저 스프링을 기반으로 개발된 다음과 같은 API 가 있다고 하자.

1. 게시판 목록 조회 API
/boards/list.json

2. 게시판의 게시물 목록 조회 API
/boards/{boardId:[\\p{Digit}]+}/threads/list.json

Postman 을 실행하고 호출 방법(1) , URL (2) 입력하고 Send(3) 버튼을 클릭하면 결과(4) 를 확인 할 수 있다. AJAX 기반의 웹 프로그램을 개발하거나 모바일 API 를 개발하는 경우라면 아주 쉽게 개발된 API 를 테스트할 수 있다.

그림1. Postman 실행화면

인증이 필요한 API 이고 Spring Security 를 사용하고 있다면 간단한 설정 추가를 통하여 Basic Authentication 기능을 추가할 수 있고 Postman 에서는 요청을 만들때 Authorization 정보를 입력(1)하여 손쉽게 인증이 요구되는 API 들에 대한 테스트가 가능하다.

그림2. Basic Auth 를 통한 요청
기본적으로 한번 Basic Authentication 이 처리되면 이후 요청부터는 세션이 생성되어 인증된 상태에서 요청이 전달된다.

앱을 개발하거나 또는 AJAX 기반의 웹 API 개발시에는 UI 개발이후에 테스트하고 디버깅을 진행하였으나 Postman 을 사용하여 API 개발과 통시에 테스트를 진행할 수 있어 개발 생산성을 향상시킬수 있었다.