Cloud Storage for Firebase는 파일의 보안을 빠르고 손쉽게 설정할 수 있도록 Cloud Storage에 대한 Firebase Security Rules라는 선언적 경로 기반 보안 모델을 제공합니다.
규칙 이해
Cloud Storage용 Firebase Security Rules는 Cloud Storage에 저장된 파일에 대한 읽기 및 쓰기 액세스 권한, 파일의 구조, 파일에 포함된 메타데이터를 결정하는 데 사용됩니다. 기본 규칙 유형은 allow
규칙이며, 선택사항으로 특정 조건이 지정되면 read
및 write
요청을 허용합니다. 예를 들면 다음과 같습니다.
// If no condition is specified, the rule evaluates to true allow read; // Rules can optionally specify a condition allow write: if <condition>; // Rules can also specify multiple request methods allow read, write: if <condition>;
경로 일치
Cloud Storage Security Rules는 Cloud Storage의 파일에 액세스하는 데 사용된 파일 경로를 비교(match
)합니다. 규칙은 정확한 경로 또는 와일드 카드 경로를 비교(match
)할 수 있으며 규칙 중첩도 가능합니다. 요청 메서드를 허용하는 일치 규칙이 없거나 조건이 false
로 판정되면 요청이 거부됩니다.
완전 일치
// Exact match for "images/profilePhoto.png" match /images/profilePhoto.png { allow write: if <condition>; } // Exact match for "images/croppedProfilePhoto.png" match /images/croppedProfilePhoto.png { allow write: if <other_condition>; }
중첩 일치
// Partial match for files that start with "images" match /images { // Exact match for "images/profilePhoto.png" match /profilePhoto.png { allow write: if <condition>; } // Exact match for "images/croppedProfilePhoto.png" match /croppedProfilePhoto.png { allow write: if <other_condition>; } }
와일드 카드 일치
match
규칙에 와일드 카드를 사용해 패턴을 비교할 수도 있습니다. 와일드 카드는 profilePhoto.png
같은 단일 문자열 또는 images/profilePhoto.png
같은 여러 경로 세그먼트를 나타내는 명명된 변수입니다.
와일드 카드를 만들려면 {string}
과 같이 와일드 카드 이름을 중괄호로 묶습니다. {path=**}
와 같이 와일드 카드 이름에 =**
를 추가하면 다중 세그먼트 와일드 카드를 선언할 수 있습니다.
// Partial match for files that start with "images" match /images { // Exact match for "images/*" // e.g. images/profilePhoto.png is matched match /{imageId} { // This rule only matches a single path segment (*) // imageId is a string that contains the specific segment matched allow read: if <condition>; } // Exact match for "images/**" // e.g. images/users/user:12345/profilePhoto.png is matched // images/profilePhoto.png is also matched! match /{allImages=**} { // This rule matches one or more path segments (**) // allImages is a path that contains all segments matched allow read: if <other_condition>; } }
여러 규칙이 파일 하나와 일치하면 모든 규칙 판정의 결과를 OR
로 결합한 결과가 적용됩니다. 즉, 파일과 일치하는 규칙이 하나라도 true
로 판정되면 결과는 true
입니다.
위 규칙에서는 condition
또는 other_condition
이 true로 판정되면 'images/profilePhoto.png' 파일을 읽을 수 있지만 'images/users/user:12345/profilePhoto.png' 파일은 other_condition
의 결과가 true일 때만 읽을 수 있습니다.
match
내에서 와일드 카드 변수를 참조하여 파일 이름 또는 경로에 대한 승인을 정의할 수 있습니다.
// Another way to restrict the name of a file match /images/{imageId} { allow read: if imageId == "profilePhoto.png"; }
Cloud Storage Security Rules는 하위로 전파되지 않으며, 규칙이 지정된 경로와 요청 경로가 일치할 때만 규칙이 평가됩니다.
요청 검증
업로드, 다운로드, 메타데이터 변경 및 삭제는 Cloud Storage로 전송된 request
를 사용하여 검증됩니다. request
변수에는 요청이 이루어지는 파일 경로, 요청 수신 시간, 새 resource
값(쓰기 요청인 경우)이 포함됩니다. HTTP 헤더 및 인증 상태도 포함됩니다.
또한 request
객체는 request.auth
객체에 사용자의 고유 ID 및 Firebase Authentication 페이로드를 포함합니다. 자세한 내용은 문서의 사용자 기반 보안 섹션을 참고하세요.
다음은 request
객체의 전체 속성 목록입니다.
속성 | 유형 | 설명 |
---|---|---|
auth |
맵<문자열, 문자열> | 사용자가 로그인하면 uid (사용자의 고유 ID) 및 token (Firebase Authentication JWT 클레임의 맵)을 제공합니다. 그렇지 않으면 null 입니다. |
params |
맵<문자열, 문자열> | 요청의 쿼리 매개변수를 포함하는 맵입니다. |
path |
경로 | 요청이 이루어지는 경로를 나타내는 path 입니다. |
resource |
맵<문자열, 문자열> | 새 리소스 값이며 write 요청에만 있습니다. |
time |
타임스탬프 | 요청을 검증하는 서버 시간을 나타내는 타임스탬프입니다. |
리소스 검증
규칙을 판정할 때 업로드, 다운로드, 수정 또는 삭제되는 파일의 메타데이터를 검증할 수도 있습니다. 이를 통해 특정 콘텐츠 유형의 파일만 업로드를 허용하거나 특정 크기보다 큰 파일만 삭제를 허용하는 등의 복잡하고 강력한 규칙을 만들 수 있습니다.
Cloud Storage용 Firebase Security Rules는 resource
객체에 파일 메타데이터를 제공하며 이 객체는 Cloud Storage 객체에 노출된 메타데이터의 키-값 쌍을 포함합니다. read
또는 write
요청에서 이러한 속성을 검사하여 데이터 무결성을 확보할 수 있습니다.
업로드, 메타데이터 업데이트, 삭제 등의 write
요청에서는 현재 요청 경로에 있는 파일의 메타데이터를 포함하는 resource
객체뿐 아니라 쓰기가 허용된 경우 쓸 파일 메타데이터 중 일부를 포함하는 request.resource
객체도 사용할 수 있습니다. 이러한 두 값을 사용하여 데이터 무결성을 확인하거나 파일 형식, 크기 등의 애플리케이션 제한사항을 적용할 수 있습니다.
다음은 resource
객체의 전체 속성 목록입니다.
속성 | 유형 | 설명 |
---|---|---|
name |
문자열 | 객체의 전체 이름입니다. |
bucket |
문자열 | 객체가 속한 버킷의 이름입니다. |
generation |
int | 이 객체의 GCS 객체 세대입니다. |
metageneration |
int | 이 객체의 GCS 객체 메타세대입니다. |
size |
int | 객체 크기(바이트)입니다. |
timeCreated |
타임스탬프 | 객체 생성 시간을 나타내는 타임스탬프입니다. |
updated |
타임스탬프 | 객체의 마지막 업데이트 시간을 나타내는 타임스탬프입니다. |
md5Hash |
문자열 | 객체의 MD5 해시입니다. |
crc32c |
문자열 | 객체의 crc32c 해시입니다. |
etag |
문자열 | 이 객체에 연결된 etag입니다. |
contentDisposition |
문자열 | 이 객체에 연결된 콘텐츠 처리입니다. |
contentEncoding |
문자열 | 이 객체에 연결된 콘텐츠 인코딩입니다. |
contentLanguage |
문자열 | 이 객체에 연결된 콘텐츠 언어입니다. |
contentType |
문자열 | 이 객체에 연결된 콘텐츠 유형입니다. |
metadata |
맵<문자열, 문자열> | 개발자가 추가로 지정한 커스텀 메타데이터의 키-값 쌍입니다. |
request.resource
는 generation
, metageneration
, etag
, timeCreated
, updated
만 제외하고 이러한 속성을 모두 포함합니다.
전체 예시
다음은 모든 규칙을 조합하여 만든 이미지 스토리지 솔루션용 규칙의 전체 예입니다.
service firebase.storage { match /b/{bucket}/o { match /images { // Cascade read to any image type at any path match /{allImages=**} { allow read; } // Allow write files to the path "images/*", subject to the constraints: // 1) File is less than 5MB // 2) Content type is an image // 3) Uploaded content type matches existing content type (if it exists) // 4) File name (stored in imageId wildcard variable) is less than 32 characters match /{imageId} { allow write: if request.resource.size < 5 * 1024 * 1024 && request.resource.contentType.matches('image/.*') && (resource == null || request.resource.contentType == resource.contentType) && imageId.size() < 32 } } } }
이제 사용자 보안 섹션에서 Firebase Authentication 인증을 통합하여 파일 액세스를 사용자별로 자세히 관리하는 방법을 알아보겠습니다.