Catch up on everthing we announced at this year's Firebase Summit. Learn more

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 安全规则中使用函数可以使它们更易于维护。

下一步

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

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