安全性規則和 Firebase 驗證

Firebase Security Rules 以支援多種複雜程度的格式提供存取權控管和資料驗證。如要建構以使用者和角色為基礎的存取系統,確保使用者資料安全無虞,請使用 Firebase AuthenticationFirebase Security Rules

識別使用者

Authentication 會識別要求存取您資料的使用者,並以變數的形式提供這項資訊,供您在規則中使用。auth 變數包含下列資訊:

  • uid指派給要求者的專屬使用者 ID。
  • tokenAuthentication 收集的值對應表。

auth.token 變數包含下列值:

欄位 說明
email 與帳戶相關聯的電子郵件地址 (如有)。
email_verified true,前提是使用者已驗證自己有權存取 email 地址。部分供應商會自動驗證他們擁有的電子郵件地址。
phone_number 與帳戶相關聯的電話號碼 (如有)。
name 使用者的顯示名稱 (如有設定)。
sub 使用者的 Firebase UID。這項 ID 在專案中不得重複。
firebase.identities 與這個使用者帳戶相關聯的所有身分識別字典。字典的鍵可以是下列任一項:emailphonegoogle.comfacebook.comgithub.comtwitter.com。字典的值是與帳戶相關聯的每個身分識別提供者的專屬 ID 陣列。舉例來說,auth.token.firebase.identities["google.com"][0] 包含與帳戶相關聯的第一個 Google 使用者 ID。
firebase.sign_in_provider 用來取得這個權杖的登入資訊提供者。可以是下列任一字串:custompasswordphoneanonymousgoogle.comfacebook.comgithub.comtwitter.com
firebase.tenant 與帳戶相關聯的 tenantId (如有)。例如:tenant2-m6tyz

如要新增自訂驗證屬性,auth.token變數也會包含您指定的任何自訂聲明

如果要求存取權的使用者未登入,auth 變數會是 null。 舉例來說,如果您想限制只有通過驗證的使用者才能讀取資料,就可以在規則中運用這項功能:auth != null。不過,我們通常建議進一步限制寫入存取權。

如要進一步瞭解 auth 變數,請參閱 Cloud FirestoreRealtime DatabaseCloud Storage 的參考說明文件。

在規則中運用使用者資訊

實務上,在規則中使用已驗證的資訊,可讓規則更強大且更具彈性。您可以根據使用者身分控管資料存取權。

在規則中,定義 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;
    }
  }
}

Realtime Database

{
  "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;
  }
}

Authentication建立自訂聲明後,您可以在 Rules 中存取自訂聲明。接著,您可以使用 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";
   }
  }
}

Realtime Database

{
  "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;
  }
}

如要查看更多運用 Authentication 的基本 Rules 範例,請參閱「基本安全性規則」。