我正在开发一个 Jetpack Compose 应用程序,用户可以将图像上传到 Firebase Storage,并且我将图像 URL 存储在 Firestore 中。我为 Firebase 存储设置了以下安全规则:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
我的上传功能如下所示:
override suspend fun uploadFile(file: File, folderName: String): String = withContext(Dispatchers.IO) {
val uniqueId: UUID = UUID.randomUUID()
val objectKey = "$folderName/$uniqueId.${file.extension}"
val storageRef: StorageReference = storage.reference.child(objectKey)
storageRef.putFile(file.toUri()).await()
storageRef.downloadUrl.await().toString()
}
即使实施这些安全规则后,仍然可以通过浏览器中的直接 URL 访问上传的文件。
我想确保这些文件只能通过我的应用程序访问。有没有办法确保 Firebase 存储中的文件只能由我的应用程序中经过身份验证的用户访问?
我了解到可以通过互联网访问下载 URL,并且我需要使用 Firebase SDK 而不是依赖这些 URL。但是,我不确定如何实现。
将文件上传到 Cloud Storage for Firebase 时,有两个选项可用于访问上传的文件。
您可以使用以“https://”开头的 URL 访问该文件,例如:
https://firebasestorage.googleapis.com/v0/b/your-project.appspot.com/file.jpg&token=token
或者使用以“gs://”开头的 URL。这种类型的 URL 是 Google Cloud Storage 原生 URL,不幸的是,许多库无法识别它。
当您单击文件并检查页面右侧的“文件位置”部分面板时,您可以在 Firebase 控制台中找到这两种类型的 URL。
如果您写入 Firestore,下载 URL 将由以下代码行返回:
storageRef.downloadUrl.await().toString()
那么很可能下载 URL 看起来像第一个示例中的 URL。正如您所看到的,URL 末尾有一个令牌,用于唯一标识存储桶中的文件。这意味着如果您知道该令牌,则该 URL 是公开可用的。
但是,令牌充当安全措施,“仅”限制那些知道令牌的用户访问。预测这样的令牌是完全不可能的,因为它是一个随机的 UUIDv4,每当文件上传到存储桶时就会自动生成。 此类 URL 无法使用
Firebase 存储安全规则进行限制。如前所述,这些类型的 URL 始终是公开的。由于它们包含令牌,因此这些 URL 也称为“公共、不可猜测的 URL”。如果您认为某个特定令牌已被泄露,您可以在 Firebase 控制台内找到“撤销选项”(如果您需要的话)。 因此安全规则仅适用于 URL 中不包含令牌的 URL,例如:
Firestore 安全规则