【问题标题】:Firebase Cloud Functions - How to get user that uploads a file?Firebase Cloud Functions - 如何获取上传文件的用户?
【发布时间】:2019-05-12 10:00:12
【问题描述】:

我有一个管理网站,可以将文件上传到 Firebase 存储中的特定文件夹。

从存储云函数中,我需要从上传文件的用户那里获取经过身份验证的 userId。我需要这个,因为当用户上传文件时,云功能启动,做一些处理,并将信息保存在实时数据库中,我需要保存上传操作的负责用户。

我看到从实时数据库云功能获取用户很简单(使用 context.auth.uid),但我没有找到任何类似的存储云功能的解决方案。

有可能吗?

Tks.

【问题讨论】:

  • 目前没有与来自 Cloud Storage 的 Cloud Functions 触发器关联的用户的元数据。解决方法是在路径中传递有关用户的信息,使用Storage security rules 以确保它们是准确的。
  • 感谢@Frank!但我的问题是经过身份验证的用户在我的存储中没有路径,我试图避免创建此路径,上传文件然后将其移动到正确的管理路径以获取用户 ID。
  • 如果您希望以安全的方式使用 UID,则必须以某种方式将其传入,无论是在路径中还是在元数据中。
  • 我很确定给定的答案是正确的。它演示了如何将 uid 添加到元数据中,并使用安全规则来确保它是正确的。

标签: node.js firebase google-cloud-functions firebase-storage


【解决方案1】:

我想我会提供工作代码,因为 Ali Abbas 的回答并不完全正确。

在上传期间将自定义元数据添加到文件中。您必须使用 customMetadata string>string 对象,如下所示。

firebase.storage().ref("/location/path").put(file, {customMetadata: {'uid': firebase.auth().currentUser.uid}})

接下来,我们需要验证上传的所有文件是否都包含此元数据并且准确无误。这是一个有效的存储安全规则:

allow write: if request.resource.metadata.uid == request.auth.uid

最后,从云函数中,以下将返回从文件元数据中获取的 uid:

object.metadata.uid

您可以确定这是上传文件的人的 uid,因为没有它就无法上传,除非您使用的是 Admin SDK。

【讨论】:

    【解决方案2】:

    您可以将自定义元数据作为包含字符串属性的对象上传:

    来自文档here:

    var metadata = {
      customMetadata: {
        'location': 'Yosemite, CA, USA',
        'activity': 'Hiking'
      }
    }
    

    然后您可以在文件(文档here)上使用getMetadata 来检索其信息,或者例如在下面的触发函数中获取customMetadata。

    例如,在我的 iOS 应用程序中,我创建了一个 StorageMetadata 并将 customMetadata 设置为 ["user":"userID_AZERRRRR"]

    在我的节点js函数中,我开发了这样的触发函数:

    exports.testStorageOnFinalize = functions.storage.object().onFinalize(uploadedObject => {
        console.log('metadata keys', Object.keys(uploadedObject.metadata));
        console.log('metadata user', uploadedObject.metadata['user']);
    })
    

    在我的日志控制台中:

    下午 3:00:20.140 信息 testStorageOnFinalize 元数据用户 userID_AZERRRRR

    风险

    根据 Doug 的评论,该解决方案并不完全安全,因为元数据可能会被伪造。

    所以,要解决这个问题,我们可以使用存储的安全规则来检查用户是否等于已识别用户:

    // Allow reads if a certain metadata field matches a desired value
    allow read: if resource.metadata.user == request.auth.uid;
    

    您可以查看存储规则here

    【讨论】:

    • 这里的问题是任何人都可以伪造元数据来假装他们是另一种用途,所以这个解决方案并不完全安全。
    • 谢谢 Doug,我们可以用一些安全规则来完成这个解决方案吗?
    • 可能。您为什么不参考存储安全规则的参考,看看是否有任何方法可以访问正在上传的文件的元数据? firebase.google.com/docs/reference/security/storage
    • 确实如此,所以我们可以检查例如if metadata.user = request.auth.uid
    • 听起来对您的回答很有帮助。
    猜你喜欢
    • 2019-04-08
    • 2019-03-23
    • 2023-04-01
    • 1970-01-01
    • 2018-05-19
    • 2018-01-28
    • 2017-09-04
    • 2021-07-30
    • 2020-09-17
    相关资源
    最近更新 更多