基本安全规则

Firebase 安全规则允许您控制对存储的数据的访问权限。灵活的规则语法意味着您可以创建与任意情况匹配的规则,涵盖对整个数据库执行的所有写入操作和对特定文档的操作等各种场景。

本指南介绍了您在设置应用和保护数据时可能需要实现的一些基本用例。但是,在您开始编写规则之前,可能需要详细了解编写时所用的语言以及这些规则的行为

如需访问和更新规则,请按照管理和部署 Firebase 安全规则中介绍的步骤进行操作。

默认规则:锁定模式

在 Firebase 控制台中创建数据库或存储实例时,您可以选择 Firebase 安全规则是限制对您的数据的访问(锁定模式)还是允许所有人访问(测试模式)。在 Cloud Firestore 和 Realtime Database 中,锁定模式的默认规则会拒绝所有用户的访问。在 Cloud Storage 中,只有经过身份验证的用户才能访问存储桶。

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

Realtime Database

{
  "rules": {
    ".read": false,
    ".write": false
  }
}

Cloud Storage

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

开发环境规则

在您开发应用的过程中,您可能希望数据有相对开放或不受限制的访问。不过,在将您的应用部署到生产环境之前,请务必更新您的规则。还要记住,如果您部署了应用,即使尚未启动,它也可以被任何人访问。

请注意,Firebase 允许客户端直接访问您的数据,而 Firebase 安全规则是阻止恶意用户访问的唯一安全措施。分别定义规则和产品逻辑有许多优点:客户端不负责强制执行安全策略,即使有缺陷的实现也不会泄露您的数据,而最重要的一点是,您不需要依赖中间服务器来保护数据。

所有经过身份验证的用户

虽然我们不建议任何已登录的用户都可以访问您的数据,但在您开发应用期间,让所有经过身份验证的用户都具有访问权限可能会很有用。

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Realtime Database

{
  "rules": {
    ".read": "auth.uid !== null",
    ".write": "auth.uid !== null"
  }
}

Cloud Storage

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

支持生产环境的规则

在您准备部署应用时,请确保您的数据受到保护,并且已正确授予用户访问权限。利用身份验证来设置基于用户的访问权限,并直接从数据库中读取,以设置基于数据的访问权限。

在您构建数据时,请同时考虑如何编写规则,因为您设置规则的方式会影响您在不同路径上限制对数据进行访问的方式。

仅限内容所有者访问

这些规则限定只有经过身份验证的内容所有者才有访问权限。只有一个用户可读写数据,并且数据路径包含该用户的 ID。

此规则适用的场景:适合数据按用户分割的情况 - 即唯一需要访问数据的用户也是创建该数据的用户。

此规则不适用的场景:不适合多个用户需要写入或读取相同的数据的情况 - 用户将覆盖数据或无法访问他们创建的数据。

如需设置此规则:创建一条规则,确认请求数据读取或写入权限的用户是拥有该数据的用户。

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow only authenticated content owners access
    match /some_collection/{userId}/{documents=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId
    }
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "$uid": {
        // Allow only authenticated content owners access to their data
        ".read": "auth !== null && auth.uid === $uid",
        ".write": "auth !== null && auth.uid === $uid"
      }
    }
  }
}

Cloud Storage

// Grants a user access to a node matching their user ID
service firebase.storage {
  match /b/{bucket}/o {
    // Files look like: "user/<UID>/path/to/file.txt"
    match /user/{userId}/{allPaths=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

既提供公共访问权限,又提供专属访问权限

此规则允许所有人读取数据集,但只有经过身份验证的内容所有者才能在给定路径上创建或修改数据。

此规则适用的场景:此规则适合以下应用:需要公开可读元素,但只有元素所有者拥有修改权限。 例如,聊天应用或博客。

此规则不适用的场景:类似于仅限内容所有者的规则,此规则不适合多个用户需要修改相同的数据的情况。用户最终会覆盖彼此的数据。

如需设置此规则:创建一条规则,对所有用户(或所有经过身份验证的用户)启用读取权限,并确认写入数据的用户是数据所有者。

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow public read access, but only content owners can write
    match /some_collection/{document} {
      allow read: if true
      allow create: if request.auth.uid == request.resource.data.author_uid;
      allow update, delete: if request.auth.uid == resource.data.author_uid;
    }
  }
}

Realtime Database

{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data

  "rules": {
    "some_path": {
      "$uid": {
        ".read": true,
        // or ".read": "auth.uid !== null" for only authenticated users
        ".write": "auth.uid === $uid"
      }
    }
  }
}

Cloud Storage

service firebase.storage {
  match /b/{bucket}/o {
    // Files look like: "user/<UID>/path/to/file.txt"
    match /user/{userId}/{allPaths=**} {
      allow read;
      allow write: if request.auth.uid == userId;
    }
  }
}

基于特性和基于角色的访问权限

如需使这些规则发挥作用,您必须为数据中的用户定义和分配特性。Firebase 安全规则根据数据库或文件的元数据中的数据检查请求,以确认或拒绝访问权限。

此规则适用的场景:如果您为用户分配了角色,此规则可以根据角色或特定用户组轻松限制访问权限。例如,如果您是在存储成绩,则可以向不同的用户组分配不同的访问权限级别:向“学生”组分配其所属内容的只读权限,向“教师”组分配教师所教科目的读写权限,并向“校长”组分配读取所有内容的权限。

此规则不适用的场景:在 Realtime Database 和 Cloud Storage 中,您的规则无法利用 Cloud Firestore 规则可以整合的 get() 方法。因此,您的数据库或文件元数据构建方式必须反映您在规则中使用的特性。

如需设置此规则:在 Cloud Firestore 中,在您可以读取的用户文档中包含一个字段,然后构建规则以读取该字段并有条件地授予访问权限。在 Realtime Database 中,创建一个数据路径,用于定义您的应用的用户并在子节点中为其授予角色。

您还可以设置身份验证中的自定义声明,然后从所有 Firebase 安全规则中的 auth.token 变量检索该信息。

数据定义的特性和角色

这些规则仅适用于 Cloud Firestore 和 Realtime Database。

Cloud Firestore

请记住,只要您的规则包含读取操作(就像下面的规则一样),您就需要为 Cloud Firestore 中的读取操作付费。

service cloud.firestore {
  match /databases/{database}/documents {
    // For attribute-based access control, Check a boolean `admin` attribute
    allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
    allow read: true;

    // Alterntatively, for role-based access, assign specific roles to users
    match /some_collection/{document} {
     allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
     allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
   }
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "${subpath}": {
        //
        ".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
        ".read": true
      }
    }
  }
}

自定义声明特性和角色

如需实现这些规则,请在 Firebase Authentication 中设置自定义声明,然后在您的规则中利用这些声明。

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": {
      "$uid": {
        // Create a custom claim for each role or group
        // you want to leverage
        ".write": "auth.uid !== null && auth.token.writer === true",
        ".read": "auth.uid !== null && auth.token.reader === true"
      }
    }
  }
}

Cloud Storage

service firebase.storage {
  // Allow reads if the group ID in your token matches the file metadata's `owner` property
  // Allow writes if the group ID is in the user's custom token
  match /files/{groupId}/{fileName} {
    allow read: if resource.metadata.owner == request.auth.token.groupId;
    allow write: if request.auth.token.groupId == groupId;
  }
}

租户特性

如需实现这些规则,请在 Google Cloud Identity Platform (GCIP) 中设置多租户,然后在您的规则中利用租户。以下示例允许来自特定租户(例如 tenant2-m6tyz)的用户执行写入操作

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For tenant-based access control, check for a tenantID
    allow write: if request.auth.token.firebase.tenant == 'tenant2-m6tyz';
    allow read: true;
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "$uid": {
        // Only allow reads and writes if user belongs to a specific tenant
        ".write": "auth.uid !== null && auth.token.firebase.tenant === 'tenant2-m6tyz'",
        ".read": "auth.uid !== null
      }
    }
  }
}

Cloud Storage

service firebase.storage {
  // Only allow reads and writes if user belongs to a specific tenant
  match /files/{tenantId}/{fileName} {
    allow read: if request.auth != null;
    allow write: if request.auth.token.firebase.tenant == tenantId;
  }
}