【问题标题】:I Cannot find the solution for Firebase Storage Rules我找不到 Firebase 存储规则的解决方案
【发布时间】:2022-01-03 00:25:06
【问题描述】:

我的 Firebase 存储规则:

service firebase.storage {
 match /b/{bucket}/o {

 match /{allPaths=**}{

  allow read: if request.auth != null;  }

 match /UsersPosts/{userId}{

  allow write: if  request.auth.uid == userId;
  allow read: if request.auth != null;
} } }

当我设置这些规则时,我无法将图像文件或任何其他文件上传到“UsersPosts/{UserId}”存储桶中的 Firebase 存储。

另一方面,当我使用这些规则时,我可以将我的文件上传到 UserPosts/{UserId} 节点或存储桶中。

rules_version = '2';

service firebase.storage {
match /b/{bucket}/o {

 match /{allPaths=**}{
 allow read: if request.auth != null;
 allow write: if request.auth != null;
                                       }

   match /UsersPosts/{userId}{

     allow write: if  request.auth.uid == userId;
      allow read: if request.auth != null;
    }
     }
      }

我希望只有具有相同 uid 的当前用户才能访问该存储桶。当我使用 Playground Rules 运行它时,一切正常。但是当我在flutter中通过应用程序运行它时会出现这些错误:

 E/StorageException(21358): StorageException has occurred.
 E/StorageException(21358): User does not have permission to access this  object.
 E/StorageException(21358):  Code: -13021 HttpResult: 403
 E/StorageException(21358): The server has terminated the upload session
 E/StorageException(21358): Caused by: java.io.IOException: {  "error":    {    "code": 403,    "message": "Permission denied."  }}
 E/StorageException(21358): Object does not exist at location.
 E/StorageException(21358):  Code: -13010 HttpResult: 404
 E/StorageException(21358): {  "error": {    "code": 404,    "message":    "Not Found."  }}
 E/StorageException(21358): java.io.IOException: {  "error": {    "code": 404,    "message": "Not Found."  }}
 E/flutter (21358): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)]    Unhandled Exception: PlatformException(download_error, Object does not             exist at location., null, null)
 E/flutter (21358): #0      StandardMethodCodec.decodeEnvelope   (package:flutter/src/services/message_codecs.dart:597:7)
   E/flutter (21358): #1      MethodChannel._invokeMethod (package:flutter/src   /services/platform_channel.dart:158:18)
   E/flutter (21358): <asynchronous suspension>
   E/flutter (21358): #2      StorageReference.getDownloadURL (package:firebase_storage/src/storage_reference.dart:142:12)
   E/flutter (21358): <asynchronous suspension>
   E/flutter (21358): #3      _AddStatusState.uploadPhoto (package:switchtofuture/MainPages/Upload/addStatuse.dart:474:26)
   E/flutter (21358): <asynchronous suspension>
   E/flutter (21358): #4      _AddStatusState.controllAndUploadData     (package:switchtofuture/MainPages/Upload/addStatuse.dart:412:28)

这是我的代码,错误发送给我:

Future<String> uploadPhoto(mImageFile) async {

  StorageUploadTask mStorageUploadTask = storageReference
    .child("UsersPosts/${Constants.myId}/_$postId.jpg/")
    .putFile(mImageFile);
 StorageTaskSnapshot storageTaskSnapshot =
    await mStorageUploadTask.onComplete;
 String downloadUrl = await storageTaskSnapshot.ref.getDownloadURL();
  return downloadUrl;
     }

当我尝试在没有任何安全规则的情况下上传时(就像任何人都可以读写),一切正常我的文件上传在 Firebase 存储上使用此路径为:

(UsersPosts>>egO4Fu2M64Svh0UUg19V7YcS0C13>>_4dec97f6-1e10-4005-8a9e-8512a7c5d434.jpg)

使用此代码“String postId = Uuid().v4();”生成的帖子 ID

这里,egO4Fu2M64Svh0UUg19V7YcS0C13 是 Constans.myId,$postId 是 4dec97f6-1e10-4005-8a9e-8512a7c5d434)

我只想保护我的数据库,因此没有人可以删除我的主存储桶,我希望我的数据库对每个经过身份验证的用户都是可读的,但只能由当前登录方式相同的具有相同 uid 的特定用户写入。

我希望我已经提供了所有需要专家来查找错误的信息。我是学生,不是专业人士。我在谷歌搜索了 3 个多小时,但没有找到任何解决方案。如果我不能保护我的每一个 Bucket,那还有什么意义呢?我的应用程序安全性为零。 :(

【问题讨论】:

  • 这里有很多我们看不到的变量,比如Constants.myId$postId。我们需要看到一切都符合安全规则的要求。请对正确的值进行硬编码,或显示调试日志以显示这些值是您所期望的。
  • 当我尝试在没有任何安全规则的情况下上传(就像任何人都可以读取和写入)时,一切正常我的文件上传在 Firebase 存储上使用此路径为 (UsersPosts>>egO4Fu2M64Svh0UUg19V7YcS0C13>>_4dec97f6-1e10- 4005-8a9e-8512a7c5d434.jpg) ----- 使用此代码生成的帖子 id (String postId = Uuid().v4();) ----- 这里 egO4Fu2M64Svh0UUg19V7YcS0C13 是 Constans.myId,$postId 是 4dec97f6- 1e10-4005-8a9e-8512a7c5d434)
  • 此外,当应用打开时,uid 存储在 Constants.myId 中,我打印了它,它工作正常

标签: flutter dart firebase-authentication firebase-storage firebase-security


【解决方案1】:

您实际上是在 UsersPosts/{userId}/{postId} 写的,但您的规则仅匹配 UsersPosts/{userId}

你需要使用通配符

match /UsersPosts/{userId}/{postId} {
}

或递归通配符,如果您需要递归匹配

match /UsersPosts/{userId}/{document=**} {
}

为了匹配你的路径。

在您提供的第二个示例中,您尝试访问的路径与第一条规则 match /{allPaths=**} 匹配并允许,但它不应用任何基于 userId 的限制。

更多详细信息在这里Secure data in Cloud Firestore

【讨论】:

  • 嗨 Bistru,我在实施你的解决方案后刷新,我工作了,天哪,你救了我 :) 真的很感激!!
  • 我认为您还应该从上传路径中删除最新的“/”。 "UsersPosts/${Constants.myId}/_$postId.jpg/" -> "UsersPosts/${Constants.myId}/_$postId.jpg"
  • 是的!你是对的,我做到了,而且成功了!你拯救了我的一天:)
  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-11
  • 2021-03-05
  • 2017-08-14
  • 2021-07-19
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
相关资源
最近更新 更多