Firebase 安全规则允许您控制对存储数据的访问。灵活的规则语法意味着您可以创建匹配任何内容的规则,从对整个数据库的所有写入到对特定文档的操作。
本指南描述了您在设置应用程序和保护数据时可能希望实施的一些更基本的用例。然而,在您开始编写规则之前,您可能希望了解更多有关规则编写语言及其行为的信息。
要访问和更新您的规则,请按照管理和部署 Firebase 安全规则中概述的步骤进行操作。
默认规则:锁定模式
当您在 Firebase 控制台中创建数据库或存储实例时,您可以选择您的 Firebase 安全规则是限制对您的数据的访问(锁定模式)还是允许任何人访问(测试模式)。在 Cloud Firestore 和实时数据库中,锁定模式的默认规则拒绝所有用户访问。在 Cloud Storage 中,只有经过身份验证的用户才能访问存储桶。
云端 Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
实时数据库
{
"rules": {
".read": false,
".write": false
}
}
云储存
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
开发环境规则
在开发应用程序时,您可能希望以相对开放或不受限制的方式访问您的数据。在将应用程序部署到生产环境之前,请确保更新您的规则。还请记住,如果您部署了您的应用程序,它就可以公开访问——即使您还没有启动它。
请记住,Firebase 允许客户端直接访问您的数据,而 Firebase 安全规则是阻止恶意用户访问的唯一保障。与产品逻辑分开定义规则有许多优点:客户端不负责强制执行安全性,错误的实现不会危及您的数据,最重要的是,您不依赖中间服务器来保护数据不受外界影响。
所有经过身份验证的用户
虽然我们不建议让任何已登录的用户都可以访问您的数据,但在您开发应用程序时为任何经过身份验证的用户设置访问权限可能会很有用。
云端 Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
实时数据库
{
"rules": {
".read": "auth.uid !== null",
".write": "auth.uid !== null"
}
}
云储存
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
生产就绪规则
当您准备部署您的应用程序时,请确保您的数据受到保护并且正确授予您的用户访问权限。利用身份验证设置基于用户的访问并直接从数据库中读取以设置基于数据的访问。
考虑在构建数据时编写规则,因为设置规则的方式会影响您如何限制对不同路径上的数据的访问。
仅限内容所有者访问
这些规则仅限制对内容的经过身份验证的所有者的访问。数据只能由一个用户读写,数据路径包含用户的ID。
当此规则适用时:如果数据被用户孤立,则此规则适用 - 如果需要访问数据的唯一用户是创建数据的同一用户。
当此规则不起作用时:当多个用户需要写入或读取相同数据时,此规则集不起作用 - 用户将覆盖数据或无法访问他们创建的数据。
要设置此规则:创建一个规则,确认请求访问读取或写入数据的用户是拥有该数据的用户。
云端 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
}
}
}
实时数据库
{
"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"
}
}
}
}
云储存
// 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;
}
}
}
混合公共和私人访问
此规则允许任何人读取数据集,但将在给定路径上创建或修改数据的能力仅限于经过身份验证的内容所有者。
当此规则有效时:此规则适用于需要公开可读元素但需要限制这些元素所有者的编辑权限的应用程序。例如,聊天应用程序或博客。
当此规则不起作用时:与仅内容所有者规则一样,当多个用户需要编辑相同数据时,此规则集不起作用。用户最终将覆盖彼此的数据。
要设置此规则:创建一个规则,为所有用户(或所有经过身份验证的用户)启用读取访问权限,并确认写入数据的用户是所有者。
云端 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;
}
}
}
实时数据库
{
// 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"
}
}
}
}
云储存
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 安全规则根据数据库中的数据或文件的元数据检查请求,以确认或拒绝访问。
当此规则起作用时:如果您要为用户分配角色,则此规则可以轻松地根据角色或特定用户组限制访问。例如,如果您要存储成绩,您可以为“学生”组(只读他们的内容)、“教师”组(读和写他们的主题)和“校长”组(读所有内容)。
当此规则不起作用时:在实时数据库和 Cloud Storage 中,您的规则无法利用 Cloud Firestore 规则可以包含的get()
方法。因此,您必须构建数据库或文件元数据以反映您在规则中使用的属性。
要设置此规则:在 Cloud Firestore 中,在您的用户文档中包含一个您可以阅读的字段,然后构建您的规则以读取该字段并有条件地授予访问权限。在实时数据库中,创建一个数据路径来定义您的应用程序的用户并授予他们在子节点中的角色。
您还可以在身份验证中设置自定义声明,然后从任何 Firebase 安全规则中的auth.token
变量中检索该信息。
数据定义的属性和角色
这些规则仅适用于 Cloud Firestore 和实时数据库。
云端 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"
}
}
}
实时数据库
{
"rules": {
"some_path": {
"${subpath}": {
//
".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
".read": true
}
}
}
}
自定义声明属性和角色
要实施这些规则,请在 Firebase 身份验证中设置自定义声明,然后在您的规则中利用这些声明。
云端 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": {
"$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"
}
}
}
}
云储存
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
云端 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;
}
}
实时数据库
{
"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
}
}
}
}
云储存
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;
}
}