Amazon S3简单的Javascript客户端文件上传问题

时间:2014-11-29 00:56:26

标签: javascript file-upload amazon-web-services amazon-s3

我只是没有让这个aws s3工作。现在尝试了几件事,包括角度的例子(我不想使用fineUploader!),每次我都会遇到同样的错误。现在,我已经得到了一个非常可靠的例子,说明了我的错误需要做些什么:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha256.js">    </script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script>
<script>
    var POLICY_JSON = { "expiration": "2014-12-20T12:00:00.000Z",
        "conditions": [
            {"bucket": "<AWS_BUCKET_NAME>"},
            ["starts-with", "$key", "russ"],
            {"acl": "public-read"},
            {"success_action_redirect": "http://localhost:3000/successful_upload.html"},
            ["starts-with", "$Content-Type", "image/"]
        ]};

    var policyBase64 = btoa((JSON.stringify(POLICY_JSON)));
    console.log('<POLICY> -->');
    console.log(policyBase64);
    var hash = CryptoJS.HmacSHA256(policyBase64, "<AWS_SECRET_KEY>");
    var base64 = CryptoJS.enc.Base64.stringify(hash);
    console.log('<SIGNATURE> -->');
    console.log(base64);

</script>


<form action="http://bucket.s3.amazonaws.com" method="post" enctype="multipart/form-data">
    <input type="hidden" name="acl" value="public-read" />
    <input type="hidden" name="success_action_redirect" value="http://localhost:3000/successful_upload.html" />
    <input type="hidden" name="AWSAccessKeyId" value="<AWS_ACCESS_KEY>" />
    <input type="hidden" name="Policy" value="<POLICY>" />
    <input type="hidden" name="Signature" value="<SIGNATURE>" />


    Key to upload: <input type="input" name="key" value="test.jpg" /><br />
    Content-Type: <input type="input" name="Content-Type" value="image/jpeg" /><br />
    File: <input type="file" name="file" /> <br />

    <input type="submit" name="submit" value="Upload to Amazon S3" />
</form>
</body>
</html>

将所有内容复制到一个新的.html文件中并打开一次,将值输入控制台,使用出来的值填写表单并再次打开index.html。我的大问题是每当我尝试将某些内容上传到我们的桶中时我得到的答案。

<Error>
    <Code>InvalidRequest</Code>
    <Message>
        The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.
    </Message>
    <RequestId><MYREQUESTID></RequestId>
    <HostId>
        <MYHOSTID>
    </HostId>
</Error>

有什么建议吗?我现在正在为此工作2天,搜索和阅读亚马逊文档。它与我需要做的签名有关(新的aws用途似乎被命名为&#39; v4&#39;)并且因为它位于德国法兰克福而被用于桶。但我还没有得到如何增强我的要求以满足他们的需求。

3 个答案:

答案 0 :(得分:2)

您正在构建V2策略文档,并使用带有AWS Secret的HMAC对其进行签名,这只能通过V2完成。

使用V4,您必须构建一个&#34;签名密钥&#34;用于对请求进行签名,并将您用于构建该密钥的信息包含在策略中x-amz-credential,以及其他一些更改。

http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html

生成签名的实际方法也不同。

http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html

你应该从这里开始......

http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html

正如您现在可能发现的那样,法兰克福以及2014年或之后部署的任何其他S3区域都不支持签名版本2.所有地区都支持签名版本4.

答案 1 :(得分:1)

虽然Michael的回答是正确的,但我还想补充一点,我们有一个JavaScript SDK,允许您直接从浏览器调用AWS API,只需最少的JavaScript代码。 SDK负责处理低级细节 - 我们称之为无差别的繁重工作 - 例如HTTP连接,重试和签名。 更多详情请见http://aws.amazon.com/sdk-for-browser/

此外,请勿将密钥存储在客户端的JavaScript代码中(在签名生成代码中)。任何有权访问您的访问密钥(在表单中可见)和您的密钥(在您的JavaScript代码中)的人都可以访问您的帐户,并具有与此密钥对的IAM策略相关联的权限。

如果您考虑使用S3上载表单,最佳做法是在服务器端生成表单。通过执行此操作,您的密钥将保留在您的服务器上,而不会在客户端公开。

答案 2 :(得分:1)

好的,所以答案并不那么简单,但我用它作为现实世界的程序化例子解决了它。 - &GT; https://github.com/emil10001/AWS-NodeJS-AngularJS-Demos

这就是我最终得到的服务器代码:

        var urlPair = {};
        var key = crypto.createHash('sha1')
            .update(new Date().getTime().toString() + Math.random().toString())
            .digest('base64').toString();

        urlPair['s3Key'] = key;
        var putParams = {
            Bucket: 'bucket',
            Key: key,
            ACL: 'public-read',
            ContentType: 'application/octet-stream'
        };

        s3.getSignedUrl('putObject', putParams, function (err, url) {
            if (!!err) {
                console.log(err);
                return;
            }
            urlPair['s3PutUrl'] = url;
            urlPair['s3GetUrl'] = 'https://bucket.s3.amazonaws.com/' + qs.escape(key);
            res.json(urlPair);
            res.end();
        });

s3PutUrl以及s3GetUrl都返回有效语句以允许您上传文件。但这只是其中的一部分。通过他的例子关注emil10001,你将得到工作代码和工作环境!