본문 바로가기

Cloud/GCP

[GCP] Cloud CDN을 위한 서명된 URL 만들기(JavaScript)

배경

GCP에 버킷을 만들고 CDN을 적용하면 이미지나 영상 같은 정적 파일을 빠르게 전송할 수 있습니다. 하지만 버킷을 외부에 공개하면 파일을 보호할 수 없기 때문에 좋지 않고, 그렇다고 비공개로 설정하면 클라이언트에서 파일을 가져올 수 없습니다. 이에 대한 대안으로 서명된 인증 URL을 통해 제한된 권한으로 파일을 가져올 수 있습니다.


서명된 URL?

권한이 없어도 버킷에 접근할 수 있는 인증 URL입니다. 이 URL이 있으면 누구나 버킷의 파일에 접근할 수 있게 됩니다. URL에는 요청을 수행하는 데 필요한 제한된 권한시간이 포함되며, URL 쿼리를 통해 인증 정보를 전송합니다.

 

https://cloud.google.com/storage/docs/access-control/signed-urls?hl=ko


시작하기 전에...

이 글은 아래의 조건이 필요합니다.

 

1. GCP를 이용 중이다.

2. 비공개 버킷이 있다.

3. 버킷에 Cloud CDN이 적용되어 있다.

4. 백엔드에서 버킷 접근을 위한 서비스 계정(Key 파일)이 있다.

 

GCS 버킷에 업로드하기

https://sty110357.tistory.com/136

 

GCS 버킷에 CDN 적용하기

https://sty110357.tistory.com/137

 

 

그럼 시작해보겠습니다.


 

1.  URL 서명 키 만들기

'GCP > Cloud CDN > 생성된 CDN 백엔드 > 수정 > Cache Performance 단계 > 제한된 콘텐츠 항목'으로 이동해 키를 생성해줍니다.

 

 

'서명 키 값'은 서명 키를 만들면 볼 수 없기 때문에, 미리 텍스트 파일에 저장해 두면 좋습니다.

 

바로 아래 항목에 '커스텀 응답 헤더'가 있는데, cross-origin 환경일 때 버킷에 접근할 수 있도록 해줬습니다.

헤더 이름: Cross-Origin-Resource-Policy

헤더 값: cross-origin

 

2.  Cloud CDN에 권한 부여

버킷이 비공개이므로 Cloud CDN이 버킷에 접근할 수 있는 권한을 부여해야 합니다. 아래 명령어를 GCP 콘솔에 입력해서 권한을 부여해 주세요.

 

gsutil iam ch \
  serviceAccount:service-프로젝트번호@cloud-cdn-fill.iam.gserviceaccount.com:objectViewer \
  gs://버킷명

 

프로젝트 번호는 대시보드에서 프로젝트를 클릭하면 확인할 수 있습니다.

https://console.cloud.google.com/projectselector2/home/dashboard?hl=ko

 

위에서 만든 서비스 계정은 프로젝트가 아닌 Cloud CDN이 소유하기 때문에 서비스 계정 목록에는 표시되지 않습니다. 

 

3. 서명된 URL 만들기

import * as crypto from 'crypto';
import * as URLSafeBase64 from 'urlsafe-base64';

async getGcsSignedUrl(filePath: string) {
  const url = `https://cdn.example.com/${filePath}`;
  const key_name = 'KEY_NAME';
  const key = 'KEY';
  const expiration = Math.round(new Date().getTime() / 1000) + 600; //ten minutes after, in seconds
  const decoded_key = URLSafeBase64.decode(key);

  let urlToSign =
    url +
    (url.indexOf('?') > -1 ? '&' : '?') +
    'Expires=' +
    expiration +
    '&KeyName=' +
    key_name;

  const hmac = crypto.createHmac('sha1', decoded_key);
  const signature = hmac.update(urlToSign).digest();
  const encoded_signature = URLSafeBase64.encode(signature);

  urlToSign += '&Signature=' + encoded_signature;
  return urlToSign;
}

 

결과는 아래와 같습니다.

https://cdn.example.com/myfile.png?Expires=1679002054&KeyName=cdn-sign-key&Signature=UXOUGxFnNEz6OCi0paJwxU-8ZuE

참고

  • https://cloud.google.com/cdn/docs/using-signed-urls?hl=ko

'Cloud > GCP' 카테고리의 다른 글