经过身份验证的用户的Firebase存储规则专用URL(无下载URL或库)

问题描述 投票:0回答:1

是否可以在不使用<img/>getDownloadURL库的情况下在Web应用程序中私密显示图像(@firebase/storage

例如,我尝试了以下规则:

rules_version = '2';

service firebase.storage {
  match /b/{bucket}/o {
    match /{userId}/images/{allPaths=**} {
      allow write: if request.auth.uid == userId;
      allow read: if request.auth.uid == userId;
    }
  }
}

并且我的html页面包含类似图像的图像:

<img src="https://firebasestorage.googleapis.com/v0/b/{projectId}.appspot.com/o/{userId}/images/yolo.jpg?alt=media/>

[此页面仅显示给经过身份验证的用户,但是即使成功登录后,当我尝试渲染上面显示的图像时,我仍然会得到403

我猜是img https请求不包含有关授权的任何信息,这就是为什么它失败的原因。

因此,我的问题是,不使用Firebase库下载图像/文件,有没有办法获取私有存储文件?

javascript firebase firebase-authentication firebase-storage firebase-security
1个回答
0
投票

正如我的问题NO]中的注释部分所讨论的,如果不通过客户端的请求来获取图像,就无法实现我的目标。

但是,我设法找到了适合我们应用程序需求的解决方案,因此让我分享一下。

首先,首先是更多内容。我们的应用程序的内容,即所见即所得的演示文稿编辑器,是由用户生成的,也可以在以后的阶段公开共享。这就是为什么我们需要拥有私有和公共资产。

此外,共享内容是HTML,也是用户正在编辑的内容,因此它不是,或者至少对我来说不是,直接附加请求以获取图像。

幸运的是,我们确实使用了Web组件,由于内容有阴影,这使我能够混淆图像公开时不需要的内容。

分别在这种情况下,我没有使用<img/>元素,而是使用了组件<deckgo-lazy-img/>

npm install @deckdeckgo/lazy-img

这就是为什么我改进了组件并添加了新的boolean属性custom-loader的原因。当设置为true时,该组件将冒泡一个事件custom-load,该事件可能会被拦截,以便使用自定义代码加载图像,而不是在与视口相交时显示图像。

因此,我只是添加了要在我的应用中找到我的components元素,然后将该属性设置为true。还需要注意的是,属性没有反映在dom中,因此我的原始问题已得到解决,因为用户的内容不会更改。

html:

<deckgo-lazy-img img-src='https://firebasestorage..'/>

javascript:

document.querySelector('deckgo-lazy-img').customLoader = true;

最后,我添加一个事件侦听器以拦截自定义事件:

document.addEventListener('customLoad', this.onCustomLoad, false);

提供信息imgElement(阴影图像)和imgSrc(作为组件属性提供的图像的实际来源)的自定义。

然后,我要保留上述规则,然后使用登录用户的令牌对请求进行身份验证,然后通过Firebase存储处理图像的加载。

try {
  const rawResponse: Response = await fetch(detail.imgSrc, {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${your_user_auth_token}`
    }
  });

  if (!rawResponse || !rawResponse.ok) {
    console.error(`Image ${detail.imgSrc} can not be fetched.`);
    return;
  }

  const blob: Blob = await rawResponse.blob();
  detail.imgElement.src = URL.createObjectURL(blob);
} catch (err) {
  console.error(err);
}

((detail是自定义事件的详细信息)。

我们的项目是开源的,这里是我添加到正在开发的PR中的相关commit

© www.soinside.com 2019 - 2024. All rights reserved.