是否可以在不使用<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库下载图像/文件,有没有办法获取私有存储文件?
正如我的问题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。