一尘不染

Amazon S3 POST api,并使用NodeJS签名策略

node.js

我正在尝试构建一个允许用户从支持NodeJS的网站直接将文件上传到我的Amazon S3存储桶的版本。看来,除了
实际的亚马逊文档
以外,这里仅有的所有教程都已经过时了。

我一直在关注的基本信息,但是它又过时了。它没有要crypto纠正的方法调用,因为它试图将原始JavaScript对象传递给该update方法,因为它不是字符串或缓冲区,所以会引发错误。

我也一直在寻找 knoxnpm软件包的源代码。它没有内置的POST支持-我完全理解,因为一旦它具有正确的字段,它就是由浏览器执行POST。Knox似乎具有签署策略的正确代码,并且我已尝试根据此代码使我的代码正常工作……但同样无济于事。

这是我想出的代码。它产生一个以base64编码的策略,并创建一个签名…但是当我尝试上传文件时,根据Amazon的说法,这是错误的签名。

var crypto = require("crypto");
var config = require("../../amazonConfig.json");

exports.createS3Policy = function(callback) {
  var date = new Date();

  var s3Policy = {
    "expiration": "2014-12-01T12:00:00.000Z",
    "conditions": [
      {"acl": "public-read"}, 
      ["content-length-range", 0, 2147483648],
      {"bucket": "signalleaf"}, 
      ["starts-with", "$Cache-Control", ""],
      ["starts-with", "$Content-Type", ""],
      ["starts-with", "$Content-Disposition", ""],
      ["starts-with", "$Content-Encoding", ""],
      ["starts-with", "$Expires", ""],
      ["starts-with", "$key", "/myfolder/"], 
      {"success_action_redirect": "http://example.com/uploadsuccess"},
    ]
  };

  var stringPolicy = JSON.stringify(s3Policy).toString("utf-8");
  var buffer = Buffer(stringPolicy, "utf-8");

  var encoded = buffer.toString("base64");
  var signature = crypto.createHmac("sha1", config.secretKey)
    .update(new Buffer(stringPolicy, "utf-8")).digest("base64");


  var s3Credentials = {
    s3PolicyBase64: encoded,
    s3Signature: signature
  };

  GLOBAL.s3creds = s3Credentials;

  callback(s3Credentials);
};

我显然在这里做错了。但是我不知道该怎么办。任何人都可以帮助您确定我在做什么错吗?我的问题在哪里? 是否有人有有效的教程来说明如何从NodeJSv0.10.x生成带有签名的正确的Amazon S3策略,并进行签名,以将其发布到s3 REST api?


阅读 282

收藏
2020-07-07

共1个答案

一尘不染

好吧,我终于想通了。在玩了很长时间的随机猜谜游戏之后,我心想

“也许我需要签署base64编码策略”-我

BAM 就是这样。

我还重新排列了条件以匹配表单的发布方式,尽管我不确定这会有所不同。

var crypto = require("crypto");
var config = require("../../amazonConfig.json");

exports.createS3Policy = function(contentType, callback) {
  var date = new Date();

  var s3Policy = {
    "expiration": "2014-12-01T12:00:00.000Z", // hard coded for testing
    "conditions": [
      ["starts-with", "$key", "somefolder/"], 
      {"bucket": "my-bucket-name"}, 
      {"acl": "public-read"}, 
      ["starts-with", "$Content-Type", contentType],
      {"success_action_redirect": "http://example.com/uploadsuccess"},
    ]
  };

  // stringify and encode the policy
  var stringPolicy = JSON.stringify(s3Policy);
  var base64Policy = Buffer(stringPolicy, "utf-8").toString("base64");

  // sign the base64 encoded policy
  var signature = crypto.createHmac("sha1", config.secretKey)
    .update(new Buffer(base64Policy, "utf-8")).digest("base64");

  // build the results object
  var s3Credentials = {
    s3Policy: base64Policy,
    s3Signature: signature
  };

  // send it back
  callback(s3Credentials);
};

希望这会帮助遇到相同问题的其他人。

2020-07-07