Foundry
파일 업로드 시스템 설계
중급
핵심

서명된 주소로 직접 업로드

앱이 경로에서 빠지면 무엇을 대신 만들어야 하는가

앱 서버는 권한을 확인하고 서명된 주소만 내려줍니다. 파일은 클라이언트가 스토리지로 직접 보내고, 스토리지가 그 서명을 검증합니다. 앱이 경로에서 빠지므로 파일 크기가 앱의 부담과 무관해집니다.

그 대가로 앱은 업로드를 보지 못합니다. 서명이 무엇을 담고 무엇을 못 하는지를 아는 것이 이 개념의 전부입니다.

서명이 담는 것과 서명이 해결하지 않는 것의 비교 서명이 담는 것 만료 시각 허용 크기 상한 콘텐츠 타입 대상 경로와 메서드 스토리지가 서명을 직접 검증한다 서명이 못 하는 것 내용 검증 메타데이터 기록 완료 여부 통보 중복 판정 앱이 경로에서 빠졌으니 따로 만들어야 한다

서명에 조건을 박는다

서명은 단순한 접근 허가가 아니라 조건이 붙은 허가입니다. 조건을 서명에 넣으면 스토리지가 대신 거절해 줍니다.

조건넣지 않으면
만료주소가 유출되면 영구 업로드 권한이 된다
크기 상한100GB 를 올려 요금과 디스크를 태울 수 있다
콘텐츠 타입이미지 자리에 실행 파일이 들어온다
대상 경로남의 경로에 덮어쓸 수 있다

만료는 짧게 잡습니다. 업로드를 시작할 시간만 있으면 되고, 큰 파일은 시작 후 오래 걸려도 됩니다. 서명이 만료돼도 진행 중인 전송은 끊기지 않기 때문입니다.

앱이 모른다는 문제

파일이 앱을 거치지 않으니 앱은 세 가지를 모릅니다. 업로드가 끝났는지, 무엇이 올라갔는지, 그것이 유효한지입니다.

그래서 완료 통보 경로를 따로 만듭니다. 방법은 둘입니다.

방법동작약점
클라이언트가 알린다업로드 후 앱에 완료 요청을 보낸다클라이언트가 죽으면 통보가 안 온다
스토리지가 알린다객체 생성 이벤트를 앱이 받는다지연이 있고 이벤트 유실 대비가 필요하다

실무에서는 둘을 함께 씁니다. 빠른 경로는 클라이언트 통보, 안전망은 스토리지 이벤트입니다. 한쪽만 두면 통보를 못 받은 파일이 스토리지에만 남습니다.

클라이언트 검사는 통제가 아니다

서명을 발급할 때 클라이언트가 보낸 파일명과 크기를 그대로 믿으면 안 됩니다. 클라이언트는 고쳐 보낼 수 있는 쪽입니다. 조건은 서명 안에 박아야 스토리지가 강제합니다.

이 구분이 면접에서 자주 갈립니다. 크기 제한을 화면에서만 하고 서명에 넣지 않으면, 요청을 직접 만들어 보내는 것으로 우회됩니다.

면접에서 이렇게 나옵니다

Q.서명된 주소로 직접 업로드하는 방식을 설명해주세요

앱 서버가 권한 확인과 서명 발급만 하고 파일은 클라이언트가 스토리지로 직접 보냅니다.

1) 클라이언트가 앱에 업로드 허가를 요청한다
2) 앱이 권한을 확인하고 조건이 박힌 서명 주소를 내려준다
3) 클라이언트가 그 주소로 파일을 직접 올린다
4) 스토리지가 서명과 조건을 검증한다

얻는 것은 앱이 경로에서 빠지는 것입니다. 파일 크기와 동시 업로드 수가 앱의 대역폭과 스레드에 영향을 주지 않습니다.

흔한 실수: 서명을 "인증 토큰"으로만 설명하는 것. 서명은 조건이 붙은 허가이고, 만료와 크기 상한과 콘텐츠 타입과 대상 경로를 담습니다. 조건을 넣지 않으면 유출 시 영구 업로드 권한이 되고 남의 경로에도 쓸 수 있습니다.

Q.서명 만료를 짧게 잡아도 큰 파일 업로드가 끊기지 않나요

끊기지 않습니다. 만료는 업로드를 시작할 수 있는 기한이고 전송 시간 제한이 아닙니다.

서명을 제시해 전송이 시작되면 그 연결은 유지됩니다. 그래서 만료는 사용자가 파일을 고르고 업로드를 누르기까지의 시간만 덮으면 되고, 몇 분이면 충분합니다.

만료 설정결과
몇 분유출돼도 곧 쓸 수 없다. 권장
며칠주소만 새면 그 기간 내내 업로드 가능

다만 멀티파트로 나눠 올리면 파트마다 요청이 새로 나가므로, 전체 업로드가 만료보다 길어질 수 있습니다. 이때는 만료를 조금 늘리거나 파트 서명을 다시 받는 경로를 둡니다.

흔한 실수: 큰 파일을 위해 만료를 길게 잡는 것. 전송 시간과 시작 기한을 혼동한 것이고, 유출 위험만 늘립니다.

Q.직접 업로드에서 앱은 업로드 완료를 어떻게 아나요

모릅니다. 따로 만들어야 합니다. 앱이 경로에서 빠진 대가입니다.

방법동작약점
클라이언트 통보업로드 후 앱에 완료 요청클라이언트가 죽거나 앱을 닫으면 통보가 없다
스토리지 이벤트객체 생성 이벤트를 앱이 받는다지연이 있고 유실 대비가 필요하다

실무에서는 둘을 함께 씁니다. 클라이언트 통보를 빠른 경로로 쓰고, 스토리지 이벤트를 안전망으로 둡니다. 둘 다 같은 파일을 알릴 수 있으니 처리는 멱등해야 합니다.

한쪽만 두면 문제가 남습니다. 클라이언트 통보만 두면 통보 없이 스토리지에만 남은 파일이 쌓이고, 이벤트만 두면 사용자가 업로드 직후 화면에서 파일을 못 봅니다.

흔한 실수: 클라이언트 통보만으로 끝내는 것. 모바일에서 앱이 백그라운드로 가거나 죽는 것은 정상 상황이고, 그때마다 고아 객체가 생깁니다.

Q.업로드 크기 제한은 어디에 걸어야 하나요

서명 조건에 넣어야 합니다. 화면이나 클라이언트 검사는 통제가 아닙니다.

클라이언트는 고쳐 보낼 수 있는 쪽입니다. 업로드 화면에서 크기를 검사해도, 요청을 직접 만들어 보내면 그대로 통과합니다.

제한을 어디에 걸었나결과
업로드 화면에서만개발자도구나 스크립트로 우회된다
서명 조건에 넣었다스토리지가 조건을 보고 직접 거절한다

같은 이유로 콘텐츠 타입과 대상 경로도 서명에 넣습니다. 경로를 넣지 않으면 남의 파일을 덮어쓸 수 있고, 타입을 넣지 않으면 이미지 자리에 실행 파일이 들어옵니다.

흔한 실수: 서명 발급 요청에 클라이언트가 보낸 파일명과 크기를 그대로 믿고 서명에 박는 것. 값 자체가 클라이언트에서 온 것이므로, 허용 범위는 서버가 정한 정책과 대조해서 결정해야 합니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

읽었으면 문제로 확인해보세요

파일 업로드 시스템 설계 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.