보안 규칙 및 Firebase 인증

Firebase 보안 규칙은 복잡한 여러 수준을 지원하는 형식으로 액세스 제어 및 데이터 검증을 제공합니다. 사용자의 데이터를 안전하게 유지하는 사용자 기반 및 역할 기반 액세스 시스템을 구축하려면 Firebase 보안 규칙과 함께 Firebase 인증을 사용해야 합니다.

사용자 식별

인증은 데이터 액세스를 요청하는 사용자를 식별하고 해당 정보를 규칙에서 활용할 수 있는 변수로 제공합니다. auth 변수에는 다음 정보가 포함됩니다.

  • uid: 요청하는 사용자에게 할당되는 순 사용자 ID입니다.
  • token: 인증 과정에서 수집된 값의 맵입니다.

auth.token 변수에는 다음 값이 포함됩니다.

필드 설명
email 계정과 연결된 이메일 주소(있는 경우)입니다.
email_verified true는 사용자가 email 주소에 대한 액세스 권한이 있는지 확인한 경우입니다. 일부 제공업체는 자동으로 자체 이메일 주소를 확인합니다.
phone_number 계정과 연결된 전화번호(있는 경우)입니다.
name 사용자의 표시 이름(설정된 경우)입니다.
sub 사용자의 Firebase UID입니다. 프로젝트 내에서 고유합니다.
firebase.identities 사용자 계정과 연결된 모든 ID의 사전입니다. 사전의 키는 email, phone, google.com, facebook.com, github.com, twitter.com일 수 있습니다. 사전의 값은 계정과 연결된 각 ID 공급업체의 고유한 식별자 배열입니다. 예를 들어 auth.token.firebase.identities["google.com"][0]에는 계정과 연결된 첫 번째 Google 사용자 ID가 포함됩니다.
firebase.sign_in_provider 토큰을 얻기 위해 사용된 로그인 제공업체입니다. 문자열 custom, password, phone, anonymous, google.com, facebook.com, github.com, twitter.com 중 하나일 수 있습니다.
firebase.tenant 계정과 연결된 tenantId(있는 경우)입니다. 예: tenant2-m6tyz

맞춤설정된 인증 속성을 추가하려는 경우 auth.token 변수에도 지정한 모든 커스텀 클레임이 포함됩니다.

액세스를 요청하는 사용자가 로그인 상태가 아니라면 auth 변수는 null입니다. 예를 들어 인증된 사용자에게 읽기 액세스를 제한하려는 경우 규칙에서 이를 활용할 수 있습니다(auth != null). 하지만 일반적으로는 쓰기 액세스를 제한하는 것이 더 좋습니다.

auth 변수에 대한 자세한 내용은 Cloud Firestore, 실시간 데이터베이스, Cloud Storage 참조 문서를 확인하세요.

규칙에서 사용자 정보 활용

실제로 규칙에서 인증된 정보를 사용하면 더 강력하고 유연하게 규칙을 활용할 수 있습니다. 사용자 ID에 따라 데이터 액세스를 제어할 수 있습니다.

규칙에서 auth 변수의 정보(요청자의 사용자 정보)가 요청된 데이터와 연결된 사용자 정보와 일치하는 방법을 정의합니다.

예를 들어 앱에서 사용자가 자신의 데이터만 읽고 쓸 수 있는지 확인하려 할 수 있습니다. 이 시나리오에서는 auth.uid 변수와 요청된 데이터의 사용자 ID가 일치해야 합니다.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Make sure the uid of the requesting user matches name of the user
    // document. The wildcard expression {userId} makes the userId variable
    // available in rules.
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

실시간 데이터베이스

{
  "rules": {
    "users": {
      "$userId": {
        // grants write access to the owner of this user account
        // whose uid must exactly match the key ($userId)
        ".write": "$userId === auth.uid"
      }
    }
  }
}

Cloud Storage

service firebase.storage {
  // Only a user can upload their file, but anyone can view it
  match /users/{userId}/{fileName} {
    allow read;
    allow write: if request.auth != null && request.auth.uid == userId;
  }
}

커스텀 사용자 정보 정의

auth 변수를 더 활용하여 앱 사용자에게 할당되는 커스텀 필드를 정의할 수 있습니다.

예를 들어 특정 경로에서 쓰기 액세스를 가능하게 하는 '관리자' 역할을 만든다고 가정해 봅니다. 이 속성을 사용자에게 할당한 후 규칙에서 이 속성을 활용해 해당 경로의 액세스를 허용합니다.

Cloud Firestore에서는 사용자 문서에 커스텀 필드를 추가하고 규칙에 임베딩된 읽기를 사용해 이 필드의 값을 검색할 수 있습니다. 따라서 관리자 기반 규칙은 다음의 예와 비슷합니다.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents/some_collection: {
    // Remember that, in Cloud Firestore, reads embedded in your rules are billed operations
    write: if request.auth != null && get(/databases/(database)/documents/users/$(request.auth.uid)).data.admin == true;
    read: if request.auth != null;
  }
}

인증에서 커스텀 클레임을 만든 후에 규칙에서 커스텀 클레임에 액세스할 수 있습니다. 그런 다음 auth.token 변수를 사용해 이 커스텀 클레임을 참조할 수 있습니다.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For attribute-based access control, check for an admin claim
    allow write: if request.auth.token.admin == true;
    allow read: true;

    // Alterntatively, for role-based access, assign specific roles to users
    match /some_collection/{document} {
     allow read: if request.auth.token.reader == "true";
     allow write: if request.auth.token.writer == "true";
   }
  }
}

실시간 데이터베이스

{
  "rules": {
    "some_path/$sub_path": {
      // Create a custom claim for the admin role
      ".write": "auth.uid !== null && auth.token.writer === true"
      ".read": "auth.uid !== null"
      }
    }
  }

Cloud Storage

service firebase.storage {
  // Create a custom claim for the admin role
  match /files/{fileName} {
    allow read: if request.auth.uid != null;
    allow write: if request.auth.token.admin == true;
  }
}

인증을 활용한 기본 규칙의 예를 더 살펴보려면 기본 보안 규칙을 참조하세요.