개발

GCP에 Signed Url로 이미지 업로드하기

p829911 2021. 11. 29. 03:07

Signed URL 이란? - 권한을 포함한 URL

구글 드라이브나, 노션 같은 클라우드 저장 서비스를 사용하면 자료나 파일을 일시적으로 외부에 공유할 수 있는 기능이 있습니다. 클라우드에 저장된 파일의 링크(URL) 주소를 생성해 이를 다른 사람에게 전달하면 다른 사람은 링크 주소를 통해 파일을 확인하거나, 수정하거나, 내려받을 수 있죠.

위의 사진은 구글 스프레드 시트 화면인데요, 오른쪽 끝의 공유 버튼을 눌러보면

링크보기 창에서 뷰어, 댓글 작성자, 편집자 권한을 선택하여 권한을 가진 url을 만들 수 있습니다. 구글 스프레드 시트를 예로 설명했지만 AWS나 GCP 같은 클라우드에서도 Signed URL로 파일을 읽고 쓸 수 있습니다. 그럼 이제 실제 예시를 들어 Signed URL을 사용해보도록 하겠습니다.

Initial Condition

상황을 가정해 보겠습니다.
Client 컴퓨터는 의료 스캐너와 연결되어있고 의료 스캐너는 실시간으로 의료 슬라이드를 스캔해 이미지를 생성해 Client 컴퓨터에 저장합니다. 생성된 의료 이미지들을 AI로 분석하고, 웹 페이지에서 결과를 보고, 편집할 수 있도록 구글 스토리지에 저장할 것입니다.
여기서 Client 컴퓨터에 설치되어 있는 Agent 프로그램은 이 이미지들이 실시간으로 생성되는 것을 인지하여 구글 스토리지에 접근 권한을 가지고 있는 Spring Server로 이미지 파일과, 이미지 관련 정보를 전송하게 되고, 서버는 다시 데이터베이스에 이미지 관련 정보를 저장하고, 스토리지에 이미지 파일을 저장합니다. 이 상황에서는 서버가 권한을 가지고 있다는 이유 하나로 이미지를 단순히 업로드 하는 역할만 하고 있기 때문에 이미지 전송이 두번 일어나게됩니다. 시간과 트래픽이 많이 들겠죠. 이 문제를 Signed URL을 이용해 해결해 보겠습니다.

Improved Condition

위의 그림에서는 Client Agent가 서버에 이미지 관련 정보만을 보내고(request) 정보를 받은 스프링 서버는 권한을 가진 Signed URL을 생성하여 Agent에 다시 보내줍니다(response). 그리고 Agent에서 Signed URL로 이미지를 전송(PUT)하면 구글 스토리지에 이미지가 저장되게 됩니다. 이제 이미지 전송 한번으로 원하던 목적을 이뤄냈습니다!

그럼 이제 본격적으로 Signed URL을 만드는 방법과 Signed URL로 이미지를 보내는 방법을 알아보겠습니다.

Signed URL 만들기

https://cloud.google.com/storage/docs/access-control/signing-urls-with-helpers#storage-signed-url-object-java

 

Cloud Storage 도구를 사용한 V4 서명 프로세스  |  Google Cloud

의견 보내기 Cloud Storage 도구를 사용한 V4 서명 프로세스 이 페이지에서는 gsutil 및 Cloud Storage 클라이언트 라이브러리를 사용하여 서명된 URL을 만드는 방법을 설명합니다. 서명된 URL은 특정 Cloud St

cloud.google.com

 

위의 url에 나와있는 코드를 이미지 업로드 용으로 수정해보겠습니다.

// Generate Signed URL
    Map<String, String> extensionHeaders = new HashMap<>();
    extensionHeaders.put("Content-Type", "image/jpeg");

    URL url =
        storage.signUrl(
            blobInfo,
            15,
            TimeUnit.MINUTES,
            Storage.SignUrlOption.httpMethod(HttpMethod.PUT),
            Storage.SignUrlOption.withExtHeaders(extensionHeaders),
            Storage.SignUrlOption.withV4Signature());

url을 생성하는 매개변수는 다음과 같은 것들이 있습니다.
구글 스토리지에 저장될 path 정보(blobInfo), url이 얼마나 유효할 것인지(15분), PUT Method를 받을 것이고, 전송되는 파일의 Content-Typeimage/jpeg이고 구글에서 요구하는 V4 Signature을 사용할 것.

Signed URL로 이미지 올리기

Signed URL을 알고 있다면 이제 URL로 이미지를 전송해보겠습니다. 현재 Agent는 Golang으로 만들어져 있기 때문에 Golang 코드로 한번 예시를 들어볼게요

func uploadGcp(url string, image byte) {
    buff := bytes.NewBuffer(image)

    client := &http.Client{}

    req, _ := http.NewRequest("PUT", url, buff)
    req.Header.Set("Content-Type", "image/jpeg")
    _, err = client.Do(req)

    if err != nil {
        log.Println("Image upload failed")
    }
}

위에 코드와 같이 생성할 때 입력했던 PUT Method로 image/jpeg 형태의 byte 파일을 보내면 정상적으로 저장되는 것을 보실 수 있습니다.

이 포스트에서는 Signed URL을 사용하여 처리 시간과 네트워크 트래픽을 줄일 수 있도록 구조를 바꾼 경험을 이야기 해 보았습니다. 잘못 설명한 부분이나 첨언 하실 부분이 있다면 편하게 말씀해 주시면 감사하겠습니다.