我正在使用signed authorized S3 uploads,以便用户可以直接从浏览器将文件上传到S3,绕过我的服务器。这目前有效,但文件名与用户机器上的文件名相同。我想把它作为一个不同的名字保存在S3上。
我发布到亚马逊的formdata看起来像这样:
var formData = new FormData();
formData.append('key', targetPath); // e.g. /path/inside/bucket/myFile.mov
formData.append('AWSAccessKeyId', s3Auth.AWSAccessKeyId); // aws public key
formData.append('acl', s3Auth.acl); // e.g. 'public-read'
formData.append('policy', s3Auth.policy); // s3 policy including ['starts-with', '$key', '/path/inside/bucket/']
formData.append('signature', s3Auth.signature); // base64 sha1 hash of private key and base64 policy JSON
formData.append('success_action_status ', 200); // response code 200 on success
formData.append('file', file.slice()); // e.g. /path/on/user/computer/theirFile.mov
然而,不是最终的文件:
https://s3.amazonaws.com/mybucket/path/inside/bucket/myFile.mov
它最终成为:
https://s3.amazonaws.com/mybucket/path/inside/bucket/theirFile.mov
请注意,它有自己的文件名,但是我的基本路径。
我希望它也有我指定的文件名。
更新:更新:这一直在使用我只是将其他代码从一个存储桶复制到另一个存储桶,从而恢复原始文件名,从而使我感到困惑。
答案 0 :(得分:5)
您确定targetPath
的内容以及该数据的来源吗?
您所描述的行为是targetPath
实际上不包含/path/inside/bucket/myFile.mov
的特定情况应该发生的行为。
我建议targetPath
实际上包含值/path/inside/bucket/${filename}
- 我的意思是,字面上,字符$ { f i l e n a m e }
位于该字符串的末尾,而不是文件名你打算。
如果这是真的,那就是它应该如何运作。
如果您不知道用户将上传的文件的名称,则键值可以包含特殊变量
${filename}
,该变量将替换为上载文件的名称。例如,如果用户上传名为uploads/${filename}
的文件,则键值uploads/Birthday Cake.jpg
将成为对象名Birthday Cake.jpg
。
如果您使用要在S3中看到的文字文件名填充该变量,那么上传应该按照您的预期运行,使用您的文件名而不是上传者计算机上的文件名。
此外,更安全的方法是消除策略中的关键'starts-with'
逻辑,而是使用您希望用户上传的特定密钥为每个上传事件明确签署策略(动态)。否则,利用此表单覆盖同一密钥前缀中的其他文件并非不可能。