如何在不使用 Firebase 身份验证的情况下保护 Firebase 存储? (下一个)

Posted

技术标签:

【中文标题】如何在不使用 Firebase 身份验证的情况下保护 Firebase 存储? (下一个)【英文标题】:How to secure firebase storage without using firebase auth? (nextjs) 【发布时间】:2021-07-26 22:55:17 【问题描述】:

我正在使用 Firebase 存储在我的 next.js 页面中上传文件。客户填写表格,文件将上传到 Firebase 存储中。 (我使用的是不同的数据库)

我想知道如何只允许在此发布请求中上传文件。

import React,  useState  from "react";
import  render  from "react-dom";
import  storage  from "../src/firebase/index";

const ReactFirebaseFileUpload = () => 
  const [image, setImage] = useState(null);
  const [url, setUrl] = useState("");
  const [progress, setProgress] = useState(0);

  const handleChange = e => 
    if (e.target.files[0]) 
      setImage(e.target.files[0]);
    
  ;

  const handleUpload = () => 
    const uploadTask = storage.ref(`images/$image.name`).put(image);
    uploadTask.on(
      "state_changed",
      snapshot => 
        const progress = Math.round(
          (snapshot.bytesTransferred / snapshot.totalBytes) * 100
        );
        setProgress(progress);
      ,
      error => 
        console.log(error);
      ,
      () => 
        storage
          .ref("images")
          .child(image.name)
          .getDownloadURL()
          .then(url => 
            setUrl(url);
          );
      
    );
  ;

  return (
    <div>
      <progress value=progress max="100" />
      <br />
      <br />
      <input type="file" onChange=handleChange />
      <button onClick=handleUpload>Upload</button>
      <br />
      url
      <br />
      <img src=url || "http://via.placeholder.com/300"  />
    </div>
  );



export default ReactFirebaseFileUpload;

这是我使用开放规则的工作示例。

我的规则:

rules_version = '2';
service firebase.storage 
  match /b/bucket/o 
    match /allPaths=** 
      allow read, write: if true;
    
  

我想把上传放在 next.js api 路由系统上,所以我们有一个 api 可以调用。在我的想象中,我可以以某种方式保护这部分,然后使用标题或其他东西,或者甚至更好地在我的存储规则中定义一些东西。

我真的没有找到任何聪明的定义在那里。

请帮我指导扔这个。

【问题讨论】:

【参考方案1】:

如果有人(没有身份验证)需要上传数据,您需要让他 write 访问您存储中的特定 path

要从ref 中获取donwloadURL,它需要read 权限。

如果根据您的业务逻辑,任何人都可以上传但不需要downloadURL,您可以为所有人删除read

我绝对建议在特定的path 下上传此类文件,例如“public”,并至少像此处对图像进行文件大小和 contentType 等限制:

match /public/allPaths=** 
        allow read: if true
        allow write: if request.resource.size < 15 * 1024 * 1024
                    && request.resource.contentType.matches('image/.*') 
    

不要忘记downloadURL 是每个文件的公共访问 URL。因此,拥有该 URL 的人可以访问该文件。您需要read 规则才能从参考中获取downloadURL,但如果您从其他地方获得downloadURL,您仍然可以访问该文件。它们的制作方式不容易质疑它们,因此这是一种非常安全的方法。

如果可以的话,您可以使用管理 SDK 自行完成,只需返回 downloadURL 或使用带有存储触发器的 Firebase Cloud Functions 来侦听文件上传(访问受限,如上)并存储 @987654337 @你需要的地方。

Here 你很好地解释了所有这些如何协同工作。

【讨论】:

从昨天开始,我偶然发现了 firebase admin sdk。完全限制存储写入规则并仅使用 firebase admin sdk 进行上传是否有意义?我的代码在 api 路由上。我可以用秘密以某种方式限制 api 路由,所以我可以控制访问。这有意义吗? 是的。我会建议这样做。只要确保返回downloadURL。我更新了答案以进一步解释downloadURL。 nodeJS 管理 SDK 不支持getDownloadURL(),但您可以自行构建它,如下所示:sentinelstand.com/article/… 感谢您更新您的答案,您已经帮了我很多忙。我没有找到任何关于 nextjs 的示例以及我在不使用互联网身份验证的情况下上传数据的挑战。您能否在 nextjs 中放置一个最小的工作示例,通过使用 firebase admin sdk 和 next api 路由上传到存储?这将帮助我(我认为其他人也是)理解很多。提前致谢。 文件需要多长时间才能读取?也许getSignedUrl 就足够了。但该 downloadURL 最多只能使用 7 天。 文件在网页上使用,所以需要一直可见。能给我提供一个带有 nextjs 和 api 路由的 mpv 吗?

以上是关于如何在不使用 Firebase 身份验证的情况下保护 Firebase 存储? (下一个)的主要内容,如果未能解决你的问题,请参考以下文章

在不使用 Firebase 的情况下使用电子邮件和密码进行 Flutter 身份验证

在不使用 Firebase 身份验证的情况下设置 Firestore 安全规则

如何在视图模型中实现 Firebase 电话身份验证?

如何在不使用验证码验证器的情况下实现 Firebase 电话验证系统?

如何在不请求的情况下在firebase-auth中首次加载时获取currentUser

验证没有 Firebase 身份验证的电子邮件 - Kotlin [重复]