Firebase存储安全规则拒绝读取权限,即使“允许读取:如果为真”

sqougxex  于 2023-04-07  发布在  其他
关注(0)|答案(1)|浏览(101)

bounty明天到期。回答此问题可获得+50声望奖励。Coolkid希望引起更多关注此问题。

我可能错过了一些简单的东西。我已经在这个问题上卡住了一段时间,这是至关重要的。任何帮助都将不胜感激。
我有一个firestore存储数据库,其规则允许每个人读取(查看)图像。

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /images/{userId} {
      allow read: if true;
      allow write: if request.auth != null && request.auth.uid == userId;
    }
    match /videos/{userId} {
      allow read: if true
      allow write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

然而,当我刷新一个特定的页面时,我得到一个:

Uncaught (in promise) FirebaseError: Firebase Storage: User does not have permission to access 'images/BJBAPfJMTCOq9OypfdkZ9z1NtQ93'. (storage/unauthorized)

列出属于特定用户的所有图像的代码:

export default function MultiMedia({ handleUser }) {
  const imageListRef = useRef(ref(storage, `images/${handleUser}`));
  const [imageList, setImageList] = useState([]);

  useEffect(() => {
    listAll(imageListRef.current).then((response) => {
      response.items.forEach((item) => {
        getDownloadURL(item).then((url) => {
          setImageList((prev) => [...prev, url]);
        });
      });
    });
  }, []);

  return...

令人困惑的是,图像确实呈现在不同的页面上,主页从一个firestore数据库中提取,该数据库中有图像url和uid作为字段,以及其他字段。

export default function ImageGallery() {
  const [imageData, setImageData] = useState([]);

  useEffect(() => {
    async function reloadHome() {
      try {
        const querySnapshot = await getDocs(collection(db, "images"));

        querySnapshot.forEach((doc) => {
          setImageData((prevValue) => {
            return [
              ...prevValue,
              { imageURL: doc.data().imageURL, user: doc.data().user },
            ];
          });
        });
      } catch (error) {
        console.log(error);
      }
    }
    reloadHome();
  }, []);

图像文件夹的Firestore安全性:

rules_version = '2';
service cloud.firestore {
    match /images/{image} {
    allow read: if true;
      allow create: if isLoggedIn();
      allow update, delete: if isLoggedIn() && request.auth.uid == resource.data.user;
    }
}

我希望防止用户看到从Firebase存储中提取的用户配置文件上的图像的存储安全规则与防止同一用户看到存储在Firestore数据库中的下载URL的相同图像的规则相同。

xytpbqjk

xytpbqjk1#

由于您在users/{userId}上使用listAll(),我假设该前缀下有多个文件,并且它不是一个对象。在这种情况下,您必须为该前缀内的对象指定规则,并且只是您现在正在做的路径。例如,您当前的规则将允许阅读对象images/user1.png。请尝试使用递归通配符,如下所示:

match /images/{userId}/{file=**} {
  allow read: if true;
  allow write: if request.auth != null && request.auth.uid == userId;
}

另外,你可以像这样只更新一次,而不是在循环的每次迭代中更新状态:

useEffect(() => {
  listAll(imageListRef.current).then(async (response) => {
    const promises = response.items.map((item) => getDownloadURL(item));
    const urls = await Promise.all(promises);
    setImageList(urls);
  })
}, []);

相关问题