如何在不发出密钥的情况下允许客户端上传到Amazon S3?

时间:2010-07-30 11:59:55

标签: session amazon-s3 key

我的一个客户有一个网站,显示从客户端应用程序上传的媒体。

此应用程序最初使用FTP,但出于各种数据存储和性能原因,我们正在转向S3。

我希望能够做到的是让这个客户端直接将文件上传到我们的中央S3商店(ala dropbox / jungledisk等等),但是我没有办法在没有交钥匙的情况下这样做并将它们嵌入到应用程序中 - 不理想!

有没有办法为客户端应用程序提供会话密钥/临时上传URL /东西?这可以通过我们网站的api来完成 - 当然可以完全访问任何所需的S3密钥。

建议?

2 个答案:

答案 0 :(得分:6)

是的,这应该是可能的。您需要做的是创建一个签名的策略文件 per-upload per-user 。该策略文件,签名和其他一些数据必须由客户端程序使用POST请求发送到您希望它们使用的存储桶。亚马逊将检查请求,检查参数是否在请求附带的策略文件的限制范围内,然后允许发布。请注意,不应将此策略存储桶策略混淆。事实上,这是一个可以根据需要更改的策略,它是由客户端程序提交的(在客户端程序从您那里获得签名副本之后)。

有关详细信息,请参阅S3文档的Browser Based Uploads Using POST部分。我建议对HTML Forms部分进行详细审核,并详细介绍如何将POST参数传递给客户端(对于浏览器,您可以将HTML发送给HTML,这是文档的措辞,非-browser程序你可能需要某种API调用,然后客户端向S3提交POST)。

您还可以查看此网页,了解如何设置参数:http://s3.amazonaws.com/doc/s3-example-code/post/post_sample.html

答案 1 :(得分:3)

可以使用基于表单的HTML上传来实现:article可以很好地解释它是如何实现的。阅读article之后,您可以使用下面提到的脚本来简化生活。

这是我用来生成策略的python脚本,它的签名和base64字符串。

  

IMP:确保policy.json文件位于同一目录

import base64
import hmac, hashlib
import os
AWS_SECRET_ACCESS_KEY = 'Your Access Key'

os.system('clear')
print "This policy generator is for key : " + AWS_SECRET_ACCESS_KEY  
print "Make sure this is the correct key."
print "IMP: Please be consistent with the file policy.json small changes in space or newline can fail policy"

policy_document = file("policy.json",'rb').read()
policy = base64.b64encode(policy_document)
signature = base64.b64encode(hmac.new(AWS_SECRET_ACCESS_KEY, policy, hashlib.sha1).digest())

print
print "Policy (BASE64_POLICY to be inserted in HTML):-"
print policy
print
print "Signature:-"
print signature
print

这是我使用的相应policy.json文件:

{
  "expiration": "2014-01-01T00:00:00.00Z",
  "conditions": [
    {"bucket": "BUCKET NAME" },
    ["starts-with", "$key", "PREFIX_IF_ANY"],
    {"acl": "public-read" },
    {"success_action_redirect": "http://REDIRECTED_URL" },
    ["starts-with", "$Content-Type", "CONTENT_TYPE"],
    ["content-length-range", 0, 1048576],
  ]
}

此代码的HTML表单如下:

<html> 
    <head>
        <title>S3 POST Form</title> 
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>

    <body> 
        <form action="http://BUCKET_NAME.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
            <input type="hidden" name="key" value="picbum/${filename}">
            <input type="hidden" name="AWSAccessKeyId" value="AccessID"> 
            <input type="hidden" name="acl" value="public-read"> 
            <input type="hidden" name="success_action_redirect" value="http://REDIRECTED_URL">
            <!-- Fill these HTML fields with data generated from python script -->
            <input type="hidden" name="policy" value='BASE64_POLICY'>
            <input type="hidden" name="signature" value="SIGNATURE_GENERATED">
            <input type="hidden" name="Content-Type" value="CONTENT_TYPE">
            <!-- Include any additional input fields here -->

            File to upload to S3: 
            <input name="file" type="file"> 
            <br> 
            <input type="submit" value="Upload File to S3"> 
        </form> 
    </body>
</html>