Firebase 存储安全规则和上传文件的下载令牌

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

TLDR: 这是一个关于从

task.snapshot.ref.getDownloadURL()
返回的 URL 及其各自的
downloadToken
的问题。它询问
token
的主要作用和功能是什么,以及根据安全规则公开的文件是否有必要。


我刚刚完成了有关将文件上传和下载到 Firebase Storage 的教程指南,可在 https://firebase.google.com/docs/storage/web/upload-files 以及此 Youtube 教程中找到来自 Firebase 官方渠道

我正在为我的一个 Firebase Web 应用程序(React + Firebase)中的博客部分构建内容管理系统。

我有一个组件,允许管理员选择图像并将其上传到 Firebase 存储桶以显示在特定的博客文章中。特定

blogPost
的所有图像都应位于特定
blog-post-slug
的文件夹内。

示例:

//bucket/some-blog-post-slug/image1.jpg

每当管理员在

<input type='file'/>
上选择新文件时运行的代码:

function onFileSelect(e) {
  const file = e.target.files[0];
  const storageRef = firebase.storage().ref('some-slug/' + file.name);
  const task = storageRef.put(file);
  task.on('state_changed',
    function progress(snapshot) {
      setPercent((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
    },
    function error(err) {
      console.log(err);
    },
    function complete() {
      console.log('Upload complete!');
      task.snapshot.ref.getDownloadURL().then(function(downloadURL) {
        console.log('File available at', downloadURL);
        props.changeImageSrc(downloadURL);
      });
    }
  );
}

上面的代码返回将保存到

downloadURL
文档内的 Firestore 的
blogPost

downloadURL
具有以下格式:

https://firebasestorage.googleapis.com/v0/b/MYFIREBASEAPP.appspot.com/o/some-slug%2FILE_NAME.jpg?alt=media&token=TOKEN_VALUE

你可以看到它带有一个“基本URL”:

https://firebasestorage.googleapis.com/v0/b/MYFIREBASEAPP.appspot.com/o/some-slug%2FILE_NAME.jpg

并且 basicURL 附加有以下 GET 参数:

alt=media
token=TOKEN_VALUE

我不知道我会获得令牌,所以我现在正在测试它的行为以了解更多信息。


允许存储读取的行为:

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write;
}}}
  • 当我访问 basicURL 时:
  • 我收到一个包含上传文件详细信息的对象:
{
  "name": "some-slug/FILE_NAME.jpg",
  "bucket": "MYBUCKET",
  "generation": "GENERATION_NUMBER",
  "metageneration": "1",
  "contentType": "image/jpeg",
  "timeCreated": "2019-06-05T13:53:57.070Z",
  "updated": "2019-06-05T13:53:57.070Z",
  "storageClass": "STANDARD",
  "size": "815155",
  "md5Hash": "Mj4aCPs21NUNxXpKg1bHirFIO0A==",
  "contentEncoding": "identity",
  "contentDisposition": "inline; filename*=utf-8''FILE_NAME.jpg",
  "crc32c": "zhkQMQ==",
  "etag": "CKu4a1+u2+0ucI412CEAE=",
  "downloadTokens": "TOKEN_VALUE"
}
  • 当我访问 basicURL?alt=media
  • 图像已显示。

  • 当我访问basicURL时?alt=media&token=TOKEN_VALUE

  • 显示图像。

存储读取受限的行为:

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
}}}
  • 当我访问 basicURL 时:
  • 我收到以下错误对象:
{
  "error": {
    "code": 403,
    "message": "Permission denied. Could not perform this operation"
  }
}
  • 当我访问 basicURL?alt=media
  • 我得到相同的错误对象:
{
  "error": {
    "code": 403,
    "message": "Permission denied. Could not perform this operation"
  }
}
  • 当我访问 basicURL 时?alt=media&token=TOKEN_VALUE
  • 显示图像。

结论和问题

在我看来,安全规则

allow read: if request.auth != null;
应该阻止未经授权的用户的任何读取,但是使用
TOKEN
参数,即使对于没有
auth
对象的请求也可以访问该文件(注意:我没有记录当我运行上面的测试时)。

我知道提出超过 1 个问题并不是最佳做法,但在这种情况下我认为有必要:

问题1:

这个TOKEN主要用于什么以及为什么它会推翻

auth
规则?

问题2:

我希望这些图片能够公开,因为博客部分将面向所有用户。我应该将什么 URL 保存到 Firestore?

  • 选项1:允许所有人读取并仅保存基本URL。

  • 选项 2: 保持读取限制并保存 basicURL + 令牌。

问题3:

要在

<image src="imgSrc">
标签中显示图像,我是否需要
alt=media
参数?或者以 FILE_NAME 结尾的 basicURL 就足够了?

编辑:问题 3 答案:刚刚测试了一下,发现需要

alt=media
GET 参数才能在
<img>
标签内显示图像。


注意:如果您上传相同的文件并替换旧的文件,您每次都会得到不同的

token
,并且旧的
token
将失效。

firebase google-cloud-firestore firebase-storage
3个回答
0
投票

不幸的是,https://firebase.google.com/docs/storage/web/create-reference中描述的方法没有将授权数据添加到请求和存储规则中

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

返回

permission denied
, 使用 AngularFireStorage 模块解决了这个问题。

import { AngularFireStorage } from '@angular/fire/storage';

 constructor(     
        private storage: AngularFireStorage
    ) {

    }
getFileUrl(path: string): Observable<string> {       
        const storageRef = this.storage.ref(path);
        return from(storageRef.getDownloadURL());
    }

0
投票

问题1:

令牌不会覆盖安全规则,而是用于身份验证(类似于存储管理的密码)。


问题2: 您可以编辑规则,以便每个人都可以(全局)访问。

或者通过公开文件来单独决定每个文件,而不是编辑 firestore 规则(据我所知)。


了解更多:https://www.sentinelstand.com/article/guide-to-firebase-storage-download-urls-tokens


-1
投票
    service firebase.storage {
      match /b/{bucket}/o {
        match /{allPaths=**} {
          allow read, write;
        }
      }
    }

这是 Firebase 存储的安全权限。所有类型的数据(图像、视频等)

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