Programming/Vue.js

[Azure Storage] Vue.js에서 Azure Storage로 blob 업로드 하기

stein 2021. 8. 20. 20:56

늘 AWS만 쓰다가 이번 기회에 처음으로 Azure를 쓰게 되었다.

현재 우리 사이트 구조가
Vue.js(FE) - Django(BE) - Azure(Storage) 로 넘어가는 구조다.

현재는 대용량 파일을 업로드 할 때 Django를 거치고, Azure로 업로드 하는 방식이어서 트래픽적으로도 손해였고, Django를 굴리는 서버 자체도 스케일 업을 해야할 수도 있는 상황이었다.

 

따라서 Vue.js에서 Azure Blob Storage로 바로 업로드 하는 방법을 찾게되었다.

 

https://www.npmjs.com/package/vue-azure-blob-upload

 

vue-azure-blob-upload

VueJS service for multi-part uploading to MS Azure blob storage.

www.npmjs.com

 

내가 찾아낸건 무려 4년전에 publish 되고, 주간 다운로드수가 170대 밖에 되지 않는 작은 package였다.

미심쩍었지만 19년도 stackoverflow에 추천하는 답변이 있어서 사용하기로 결심.


문제 1(실수)

하란 대로 했는데(안함) 에러가 뜬다. console에 찍히는 버그를 찾아 들어가보니 $http가 undefined라고 한다.

그러고 다시 문서를 가보니

Dependency를 잘 확인하자

아하, axios가 설치가 안되어있구나. Vue Axios를 설치해 주었다.(https://www.npmjs.com/package/vue-axios)

문제 2

upload는 is not a function이 뜬다.

 

...?

 

문서에서 분명히 this.$azureUpload.upload(config) 라고 알려줬는데

이번엔 실수가 아니다

$azureUpload가 제대로 등록이 되지 않은건가? console을 찍어보니 $azureUpload가 function으로 나왔다.

 

그래서 this.$azureUpload.upload(config) -> this.$azureUpload(config)로 변경해보니 해결되었다. (4년동안 docs에 잘 못 적혀있던 걸까?)

 

문제 3

CORS 에러가 뜬다... 패키지에 적힌 문서에도 CORS를 맞추라는 얘기가 있다. 

저 두 링크, 모두 깨져있다.

문서에 적힌 링크의 도착지는 모두 없어진 상태. azure blob storage cors로 구글링을 하면

https://docs.microsoft.com/ko-kr/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services

 

Azure Storage 대한 CORS(원본 간 리소스 공유) 지원

CORS는 특정 도메인에서 실행되는 웹 애플리케이션이 다른 도메인의 자원에 액세스할 수 있도록 하는 HTTP 기능입니다. 각 Azure Storage 서비스에 대해 개별적으로 CORS 규칙을 설정할 수 있습니다. COR

docs.microsoft.com

https://docs.microsoft.com/ko-kr/rest/api/storageservices/set-blob-service-properties

 

Blob 서비스 속성 설정 (REST API)-Azure Storage

Blob 서비스 속성 설정 작업은 저장소 계정의 Blob service 끝점에 대 한 속성을 설정 합니다.

docs.microsoft.com

위 두 개의 페이지가 나오는데, REST api 통신으로 설정하는 방법을 알려준다.

CORS 정도는 웹페이지에서 UI로 설정해도 되잖아...!

AWS에서는 CORS 설정을 웹페이지에서 편리하게 했던 기억이 있어서, 이 악물고 REST를 안쓰는 방법을 찾아나섰다.

(애초에 저기 있는 내용을 전부 공부할 자신도 없었다)

 

 여러분, 여기 있습니다!

무려 10~20분을 찾아 헤맨끝에, 좌측 탭에 떡하니 있는 것을 발견(...) 그리고 아래의 사진과 같이 설정해주었다.

지금은 개발모드!

문제 4

자 이제 끝날 때쯤 됐는데도, 도저히 끝나질 않는다. Authentification 문제가 뜬다.

Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

뭘까.. 나는 다시 패키지의 docs를 보았다.

const config = {        
  // baseUrl for blob file uri
  //(i.e. http://<accountName>.blob.core.windows.net/<container>/<blobname>),        
  baseUrl: '',
  // Shared access signature querystring key/value prefixed with ?
  sasToken: '',
  // File object using the HTML5 File API
  file: '',
  ...
}

this.$azureUpload(config)

나는 각각 baseUrl과 sasToken에 azure의 빈 blob에서 생성한 SAS URL과 SAS Token을 넣고, file도 기존에 사용하던 img를 넣어주었다.

(30분 경과)

아, 진짜 모르겠다. Azure에 대한 기본 지식도 없고, blob도 s3랑 비슷하겠거니 해서 접근했는데, 좀 더 복잡한 것 같고...

 

그래서 그냥 sasToken을 아예 없애서, 거기서 부터 문제를 찾아보기로 했다.

 

그래서 sasToken에 빈 string을 넣고 함수를 실행시키니,

 

업로드에 성공했다.

이왜진

애초에 주석에 잘 적혀있었다.

// baseUrl for blob file uri
//(i.e. http://<accountName>.blob.core.windows.net/<container>/<blobname>),  
baseUrl: '',
// Shared access signature querystring key/value prefixed with ?
sasToken: '',
...

그리고 sasUrl이 유독 길어서 자세히 보니, baseUrl + sasToken 형식이다.

그래서 baseUrl에 sasToken을 애초에 박아놓은 주소를 넘겨서 업로드에 성공한 것이었다.

...

뒷 걸음치다 쥐잡은 격이지만, 1시간은 아꼈다라고 생각했다.


다행히 이걸로 끝이다.

다만, 현 방식으로는 빈 blob을 Front End에서 직접 생성하지 못하기 때문에, Back End에서 sasUrl을 넘겨주어야 파일을 업로드 할 수 있다는 점이 문제 아닌 문제다.(보안적으로는 더 우수하다고 생각한다)

 

(@azure/storage(https://www.npmjs.com/package/@azure/storage-blob) 라는 패키지가 있어서 금방 시도해 보았는데, 브라우저에서는 지원하지 않는다는 에러와 만났다. 일반 클라이언트단에서 azure를 만지지 못하게 하는 의도인 것 같다.)

 

Azure는 관련자료가 정말정말 너무 없던데, 본 포스트로 도움 받는 사람이 있으면 좋겠다.