Supabase Storage에 미인증 업로드 허용하기

Sungyong
5 min readSep 7, 2024

--

BaaS(Backend as a Service)중 제일 잘 나가는 Supabase는 DB와 function 뿐 만아니라 Storage도 지원한다. 심지어 S3 호환 API 모드도 지원한다.

PoC 하는 프로젝트 중 이미지 업로드하는 기능을 구현해야 한다. 정석대로라면 public은 조회만 가능하고, upload 기능은 인증된 사용자만 하는 것이 맞다.

하지만, 인증이 핵심 기능은 아닌터라, 인증은 PoC 이후 구현하기로 하고, 진행하는데, 이미지 업로드에서 걸렸다. 비인증 사용자가 업로드할 방법이 안 보이는 거다. 공식 문서에서 인증 사용자만 업로드되는 것으로 나와 있었다.

그래도 workaround로 Policy를 수동으로 설정할 수는 있었다.

Storage -> Configuration -> Policies에서 해당 bucket에 New policy 를 누른다.

Add new policy to <bucket name>에서 아무거나 선택한다. 난 처음 뜨는 것으로..

첫번째 템플릿을 바탕으로 수정할거라 Use this template을 선택한다.

편집은 오직 여기서만 할 수 있다.

policy definition에 다른 조건 다 삭제하고, 저거만 남겼다.

그리고 나서 최종 review 하고 저장.

이제 Storage policy는 아래처럼 보인다.

이제 업로드하는 함수는 아래처럼 짜기만 하면 된다.

async uploadProjectImage(projectId, file) {
console.log('uploadProjectImage', projectId, file);
try {
const fileExt = file.name.split('.').pop()
const fileName = `${projectId}.${fileExt}`
const filePath = fileName // Remove 'map/' from the path

const { data, error: uploadError } = await supabase.storage
.from('map')
.upload(filePath, file, {
upsert: true,
cacheControl: '3600',
contentType: file.type
})

if (uploadError) {
console.error('Upload error:', uploadError);
throw uploadError;
}

console.log('Upload successful:', data);

const { data: { publicUrl }, error: urlError } = supabase.storage
.from('map')
.getPublicUrl(filePath)

if (urlError) {
console.error('URL error:', urlError);
throw urlError;
}

console.log('Public URL retrieved:', publicUrl);

await this.updateProject({ id: projectId, image_url: publicUrl })

return publicUrl
} catch (error) {
console.error('Error uploading project image:', error);
if (error.message && error.message.includes('row-level security policy')) {
console.error('This is a permissions issue. Check your RLS policies for the storage bucket.');
}
throw error;
}
},

실제 테스트해보니, 업로드도 잘 되었다.

--

--