【问题标题】:Url from getSignedUrl will expire in few weeksgetSignedUrl 中的 URL 将在几周后过期
【发布时间】:2019-05-25 11:34:19
【问题描述】:

我有存储触发功能,可以调整上传图片的大小并将其替换到存储中,然后更新我数据库中的 URL

    }).then(() => {
        console.log('Original file deleted', filePath)
        const logo = storageRef.file(JPEGFilePath)
        return logo.getSignedUrl({ action: 'read', expires: date })

        // const logo = storageRef.child(JPEGFilePath)
        // return logo.getDownloadURL()

        // return storageUrl.getDownloadURL(JPEGFilePath)
    }).then((url) => {
        const newRef = db.collection("user").doc(uid)
        return newRef.set({
            profile: { profileImg: url[0] }
        }, {
                merge: true
            })
    })

这是我设置有效期的方法

const d = new Date()
const date = new Date(d.setFullYear(d.getFullYear() + 200)).toString()

不过,图片会在几周后过期(大约 2 周左右)。有谁知道如何解决这个问题?从注释代码中可以看出,我什至玩过 getDownloadURL,但这似乎在触发器中不起作用

【问题讨论】:

  • 第二个代码块看起来像是创建了一个未来 200 年的日期字符串。您更新图像到期日期的实际调用在哪里? cloud.google.com/storage/docs/lifecycle#expirationtime 说这可以通过“年龄”设置在存储桶级别进行设置——那么为什么不直接使用它而不是通过编程方式设置呢?
  • 嗨 @abelito 日期常量用于 return logo.getSignedUrl({ action: 'read', expires: date }) 。我什至尝试将其硬编码为固定日期,但结果是一样的

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


【解决方案1】:

根据以下链接:

https://stackoverflow.com/a/42959262/370321

https://cloud.google.com/nodejs/docs/reference/storage/2.5.x/File#getSignedPolicy

不确定您使用的是哪个版本的 @google/cloud-storage,但假设它是 2.5.x,看起来您在日期字段中传递的任何值都会传递到 new Date(),所以看起来像您的代码应该像我在开发工具中尝试过的那样工作。我唯一能猜到的是,您不希望文件可以保存 200 年。

根据源代码:

https://github.com/googleapis/nodejs-storage/blob/master/src/file.ts#L2358

您是否尝试过更短的时间 - 或在 mm-dd-yyyy 的日期格式中对其进行格式化?

【讨论】:

  • 我曾想过设置更短的时间,但后来我找到了这个链接,看起来我不是唯一一个有这个问题的人github.com/googleapis/nodejs-storage/issues/244如果有一些解决方法,我正在徘徊或者让 getDownloadURL 在触发器中工作
  • 我还没有考虑将日期设置为 mm-dd-yyyy 格式。我可以试一试,但需要 2 周才能找到。实际上,我已经尝试过,当我对其进行硬编码时,我将其设置为 01-01-2100,据我所知
  • 所以阅读你提到的那个线程有人说这是在创建签名 URL 的服务帐户上轮换密钥的结果:github.com/googleapis/nodejs-storage/issues/… 如果您使用默认的 Google 提供的服务帐户,则可能会发生这种情况每隔一段时间就会自动旋转。这是因为对服务帐户的更改可能会使该服务帐户创建的签名 URL 无效。解决方法似乎是指定特定服务帐户的凭据,然后从不更新该服务帐户。我建议这样做,然后再试一次!
  • 感谢您指点我 :) 现在的问题是我想从哪里获得 serviceAccount 密钥。我在哪里可以找到它?
  • 您可以在 Google 的 create & managing service accountsgetting a service account key 文档中阅读有关服务帐户的信息。
【解决方案2】:

好的,所以我尝试了一些方法,但我不知道这是否有效,所以我会在 2 周后回来将我的问题标记为已回答,如果它有效。对于那些有同样问题的人,我会试着概括一下我所做的。

1/ 从控制台下载服务帐户密钥。这是链接

https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk

2/ 将下载的 JSON 文件保存在你的函数目录中

3/ 在函数存储中包含密钥。但请注意如何设置文件的路径。这是我的问题

https://stackoverflow.com/a/56407592/11486115

更新

我刚刚在我的函数中发现了错误。我的网址是由云功能错误提供的(注释代码)

这里是完整的功能

const {
db
} = require('../../admin')


const projectId = "YOUR-PROJECT-ID"
const { Storage } = require('@google-cloud/storage');
const storage = new Storage({ projectId: projectId ,keyFilename: 'PATH-TO-SERVICE-ACCOUNT'})

const os = require('os');
const fs = require('fs');
const path = require('path');

const spawn = require('child-process-promise').spawn

const JPEG_EXTENSION = '.jpg'

exports.handler = ((object) => {
const bucket = object.bucket;
const contentType = object.contentType;
const filePath = object.name
const JPEGFilePath = path.normalize(path.format({ dir: path.dirname(filePath), name: 'profileImg', ext: JPEG_EXTENSION }))
const destBucket = storage.bucket(bucket)
const tempFilePath = path.join(os.tmpdir(), path.basename(filePath))
const tempLocalJPEGFile = path.join(os.tmpdir(), path.basename(JPEGFilePath))
const metadata = {
    contentType: contentType
}
const uid = filePath.split("/").slice(1, 2).join("")
const d = new Date()
const date = new Date(d.setFullYear(d.getFullYear() + 200)).toString()

if (!object.contentType.startsWith('image/')) {
    return destBucket.file(filePath).delete().then(() => {
        console.log('File is not an image ', filePath, ' DELETED')
        return null
    });
}

if (object.metadata.modified) {
    console.log('Image processed')
    return null
}

return destBucket.file(filePath).download({
    destination: tempFilePath
})
    .then(() => {
        console.log('The file has been downloaded to', tempFilePath)
        return spawn('convert', [tempFilePath, '-resize', '100x100', tempLocalJPEGFile])
    }).then(() => {
        console.log('JPEG image created at', tempLocalJPEGFile)
        metadata.modified = true
        return destBucket.upload(tempLocalJPEGFile,
            {
                destination: JPEGFilePath,
                metadata: { metadata: metadata }
            })
    }).then(() => {
        console.log('JPEG image uploaded to Storage at', JPEGFilePath)
        return destBucket.file(filePath).delete()
    }).then(() => {
        console.log('Original file deleted', filePath)
        //const logo = storageRef.file(JPEGFilePath)
        const logo = destBucket.file(JPEGFilePath)
        return logo.getSignedUrl({ action: 'read', expires: date })
    }).then((url) => {
        const newRef = db.collection("user").doc(uid)
        return newRef.set({
            profile: { profileImg: url[0] }
        }, {
                merge: true
            })
    }).then(() => {
        fs.unlinkSync(tempFilePath);
        fs.unlinkSync(tempLocalJPEGFile)
        console.log(uid, 'user database updated ')
        return null
    })
})

我非常有信心这现在会奏效。

【讨论】:

    猜你喜欢
    • 2016-01-11
    • 1970-01-01
    • 2019-04-01
    • 2023-02-01
    • 2016-09-03
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 2011-04-06
    相关资源
    最近更新 更多