node.js - 使用 PUT 请求生成签名 url 以将对象上传到 Google Cloud Storage 时,禁止获取 403
问题描述
我正在尝试授予对仅具有将 mp3 上传到 Google Cloud Storage 存储桶的读取权限的服务帐户的临时访问权限。
为此,我正在生成一个signedurl
,但我无法让它工作。
我正在做什么来生成 URL 并上传文件:
const config = {
action: 'write',
expires: '03-12-2019',
contentType: 'audio/mpeg'
}
const storage = new Storage({
projectId: projectId,
keyFilename: './service-account-key.json'
})
let bucketSubDirectory = storage.bucket(bucketName).file('subdirectory/in/bucket/' + songName)
bucketSubDirectory.getSignedUrl(config, (err, url) => {
if (err) {
console.error(err)
return
}
console.log(url)
// The file is now available to be written to.
let writeStream = request.put(url, {
headers: {
'Content-Type': 'audio/mpeg'
}
})
writeStream.end('New data');
writeStream.on('complete', function (resp) {
console.log(resp.statusCode + " " + resp.statusMessage)
})
})
当我执行脚本时,我得到一个403 forbidden
响应,当我尝试从浏览器访问生成的 URL 时,我得到以下信息:
<Error>
<Code>MalformedSecurityHeader</Code>
<Message>Your request has a malformed header.</Message><ParameterName>signature</ParameterName>
<Details>Signature was not base64 encoded</Details>
</Error>
知道如何解决这个问题吗?
解决方案
根据node.js 客户端库文档,该方法getSignedUrl
有一个参数config
作为参数contentType
:
内容类型
可选的
细绳
如果您提供此值,则客户端必须将此 HTTP 标头设置为相同的值。
因此,您可能需要修改您的PUT
请求以将此标头包含在 valuecontentType: audio/mpeg
中。
此外,如果您在浏览器中输入 url,您不是在发出PUT
请求,而是在发出请求GET
。
编辑:
还要检查您创建的服务帐户signedurl
是否已授予正确的权限。对于您正在运行的代码,您至少需要roles/storage.objectAdmin
角色。授予它:
gcloud projects add-iam-policy-binding yourProjectID --member yourServiceAccount --role "roles/storage.objectAdmin"
PUT
完成此操作后,用户只需对 url 发出请求即可写入文件。
const request = require('request');
let url = 'yourSignedURL'
let writeStream = request.put(url, {
headers: {
'Content-Type': 'audio/mpeg'
}
})
writeStream.end('New data');
writeStream.on('complete', function (resp) {
console.log(resp.statusCode + " " + resp.statusMessage)
})
推荐阅读
- java - 如何只构建一个包含多个不同应用程序/子项目的 JAR 文件?
- sql - 如何返回开始日期和结束日期之间的记录
- javascript - 对于循环代码,每个循环在 x 轴上的间距加倍
- firebase - React Native Crashlytics Firebase
- swift - 如何使用 UI 测试用例验证 UITableviewCell 标签和 Imageview 数据
- javascript - 可见:假和隐藏:真之间的区别
- javascript - 在反应预输入引导程序中将变量传递给`renderMenuItemChildren`
- ios - Swift Core 蓝牙通讯与 OBD2
- python-3.x - 使用 Python 设置主机名
- python - 如何在叠加图中将 RangetoolLink 与全息视图一起使用