Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Firebase 云存储安全规则中的使用条件

该指南基于学习的火力地堡安全规则语言的核心语法指南,说明如何条件添加到您的火力地堡安全规则的云存储。

云存储安全规则的主要组成部分是条件。条件是一个布尔表达式,用于确定是允许还是拒绝特定操作。对于基本规则,使用truefalse文字作为条件工作prefectly很好。但是 Cloud Storage 语言的 Firebase 安全规则为您提供了编写更复杂条件的方法,这些条件可以:

  • 检查用户身份验证
  • 验证传入数据

验证

适用于 Cloud Storage 的 Firebase 安全规则与 Firebase 身份验证集成,为 Cloud Storage 提供强大的基于用户的身份验证。这允许基于 Firebase 身份验证令牌的声明进行精细访问控制。

当已验证的用户执行对云存储的请求,则request.auth可变填充与用户的uidrequest.auth.uid )以及火力地堡认证JWT(的权利要求request.auth.token )。

此外,使用自定义身份验证时,附加的权利要求中浮现在request.auth.token字段。

当未认证的用户执行的请求,所述request.auth变量是null

使用这些数据,有几种常见的方法可以使用身份验证来保护文件:

  • 市民:忽略request.auth
  • 经过身份验证的私人:检查request.authnull
  • 用户私人:检查request.auth.uid等于路径uid
  • 组私有:检查自定义令牌的声明以匹配所选声明,或读取文件元数据以查看元数据字段是否存在

民众

不考虑任何规则request.auth上下文可以被认为是一个public的规则,因为它没有考虑到用户的认证范围内。这些规则可用于显示公共数据,例如游戏资产、声音文件或其他静态内容。

// Anyone to read a public image if the file is less than 100kB
// Anyone can upload a public file ending in '.txt'
match /public/{imageId} {
  allow read: if resource.size < 100 * 1024;
  allow write: if imageId.matches(".*\\.txt");
}

认证私人

在某些情况下,您可能希望应用程序的所有经过身份验证的用户都可以查看数据,而不是未经身份验证的用户。由于request.auth变量是null的所有未经验证的用户,所有你需要做的就是检查request.auth为了需要认证的变量存在:

// Require authentication on all internal image reads
match /internal/{imageId} {
  allow read: if request.auth != null;
}

用户私有

到目前为止,最常见的用例request.auth将是为用户提供细化的权限个别用户在他们的文件:阅读私人文件上传,从个人资料图片。

由于云存储的文件有一个完整的“路径”的文件,所有的需要,使用户控制的文件在文件名前缀一块独特的,用户识别信息(如用户的uid ),可以检查当规则被评估时:

// Only a user can upload their profile picture, but anyone can view it
match /users/{userId}/profilePicture.png {
  allow read;
  allow write: if request.auth.uid == userId;
}

团体私人

另一个同样常见的用例是允许对对象进行组权限,例如允许多个团队成员在共享文档上进行协作。有几种方法可以做到这一点:

  • 薄荷一个火力地堡验证自定义的令牌包含关于群组成员的其他信息(例如,组ID)
  • 包括组信息(例如,组ID或授权的列表uid或多个)在文件的元数据

一旦此数据存储在令牌或文件元数据中,就可以从规则中引用它:

// 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;
}

请求评估

上载,下载,元数据改变和删除所使用的评价request发送到云存储。除了用户的唯一ID,并在该火力地堡认证有效载荷request.auth如上所述目的, request变量包含在正在执行的请求中的文件路径,当接收到请求的时间,并且新的resource ,如果值请求是写。还包括 HTTP 标头和身份验证状态。

所述request对象还包含用户的唯一ID和火力地堡认证有效载荷在request.auth对象,这将进一步在说明基于用户的安全的文档的部分。

在属性的完整清单request对象可用下面:

财产类型描述
auth地图<字符串,字符串>当用户登录,提供uid ,用户的唯一ID和token ,映射一个火力地堡认证JWT权利要求中。否则,这将是null
params地图<字符串,字符串>包含请求的查询参数的映射。
path小路path表示正在以执行请求的路径。
resource地图<字符串,字符串>新的资源价值,在目前唯一write请求。
time时间戳表示评估请求的服务器时间的时间戳。

资源评估

在评估规则时,您可能还想评估正在上传、下载、修改或删除的文件的元数据。这使您可以创建复杂而强大的规则,例如只允许上传具有特定内容类型的文件,或者只允许删除大于特定大小的文件。

火力地堡安全规则的云存储提供的文件元数据resource对象,其中包含元数据的键/值对在云存储对象浮出水面。这些性质可以对被检查readwrite请求,以确保数据的完整性。

write请求(如上传,元数据更新和删除),除了resource对象,它包含了目前存在于请求路径,你也必须使用的能力,文件文件元数据request.resource对象,如果允许写入,它包含要写入的文件元数据的子集。您可以使用这两个值来确保数据完整性或强制应用程序约束,例如文件类型或大小。

在属性的完整列表resource对象可用如下:

财产类型描述
name细绳对象的全名
bucket细绳此对象所在的存储桶的名称。
generation整数谷歌云存储对象生成此对象的。
metageneration整数谷歌Cloud Storage物件metageneration此对象。
size整数对象的大小(以字节为单位)。
timeCreated时间戳表示对象创建时间的时间戳。
updated时间戳表示对象上次更新时间的时间戳。
md5Hash细绳对象的 MD5 哈希值。
crc32c细绳对象的 crc32c 哈希。
etag细绳与此对象关联的 etag。
contentDisposition细绳与此对象关联的内容处置。
contentEncoding细绳与此对象关联的内容编码。
contentLanguage细绳与此对象关联的内容语言。
contentType细绳与此对象关联的内容类型。
metadata地图<字符串,字符串>额外的、开发人员指定的自定义元数据的键/值对。

request.resource包含了所有这些与外generationmetagenerationetagtimeCreatedupdated

验证数据

火力地堡安全规则的云存储也可以用于数据验证,包括验证文件名和路径以及文件元数据属性,如contentTypesize

service firebase.storage {
  match /b/{bucket}/o {
    match /images/{imageId} {
      // Only allow uploads of any image file that's less than 5MB
      allow write: if request.resource.size < 5 * 1024 * 1024
                   && request.resource.contentType.matches('image/.*');
    }
  }
}

自定义功能

随着您的 Firebase 安全规则变得越来越复杂,您可能希望将条件集包装在可以在您的规则集中重复使用的函数中。安全规则支持自定义功能。自定义函数的语法有点像 JavaScript,但 Firebase 安全规则函数是用特定领域的语言编写的,有一些重要的限制:

  • 功能只能包含一个return语句。它们不能包含任何额外的逻辑。例如,它们不能执行循环或调用外部服务。
  • 函数可以从定义它们的范围内自动访问函数和变量。例如,该内限定的功能service firebase.storage范围有权访问resource变量,以及用于云只的FireStore,内置函数如get()exists()
  • 函数可以调用其他函数,但不能递归。总调用堆栈深度限制为 10。
  • 在版本rules2 ,功能可以定义使用变量let关键字。函数可以有任意数量的 let 绑定,但必须以 return 语句结束。

的函数被定义与function关键字和接受零个或多个参数。例如,您可能希望将上述示例中使用的两种类型的条件组合到一个函数中:

service firebase.storage {
  match /b/{bucket}/o {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }
    match /images/{imageId} {
      allow read, write: if signedInOrPublic();
    }
    match /mp3s/{mp3Ids} {
      allow read: if signedInOrPublic();
    }
  }
}

随着规则复杂性的增加,在 Firebase 安全规则中使用函数可以使它们更易于维护。

下一步

在对条件的讨论之后,您对规则有了更深入的了解,并准备好:

了解如何处理核心用例,并了解开发、测试和部署规则的工作流程: