파일 보안 설정 방법

Cloud Storage for Firebase는 파일의 보안을 빠르고 손쉽게 설정할 수 있도록 Cloud Storage에 대한 Firebase Security Rules라는 선언적 경로 기반 보안 모델을 제공합니다.

규칙 이해

Cloud StorageFirebase Security RulesCloud Storage에 저장된 파일에 대한 읽기 및 쓰기 액세스 권한, 파일의 구조, 파일에 포함된 메타데이터를 결정하는 데 사용됩니다. 기본 규칙 유형은 allow 규칙이며, 선택사항으로 특정 조건이 지정되면 readwrite 요청을 허용합니다. 예를 들면 다음과 같습니다.

// 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 RulesCloud 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 StorageFirebase Security Rulesresource 객체에 파일 메타데이터를 제공하며 이 객체는 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.resourcegeneration, 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 인증을 통합하여 파일 액세스를 사용자별로 자세히 관리하는 방법을 알아보겠습니다.