javascript - Amazon S3 POST api,并使用 NodeJS 签署策略

标签 javascript node.js amazon-web-services amazon-s3 cryptography

我正在尝试构建一个允许用户从 NodeJS 支持的网站将文件直接上传到我的 Amazon S3 存储桶的构建。除了 the actual amazon docs for this 之外,这似乎是唯一的教程。 都非常过时。

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

我也一直在寻找 the knox npm package 的来源。它没有内置 POST 支持 - 我完全理解,因为一旦它具有正确的字段,它就是浏览器在执行 POST。 Knox 似乎确实拥有签署政策的正确代码,我试图让我的代码基于此工作......但再次无济于事。

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


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);
};

我显然做错了什么,在这里。但我不知道是什么。谁能帮助确定我做错了什么?我的问题在哪里? 是否有人提供有关如何从 NodeJS v0.10.x 生成带有签名的正确 Amazon S3 策略的工作教程,用于 POST 到 s3 REST api?

最佳答案

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

"maybe i need to sign the base64 encoded policy" - me

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);
};

希望这能帮助遇到同样问题的其他人。

关于javascript - Amazon S3 POST api,并使用 NodeJS 签署策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18476217/

相关文章:

javascript - 我希望下面的按钮代码打开一个新选项卡,其中包含从 js 变量中获取的 URL

javascript - 无法循环遍历字符串来查找正则表达式模式编号

node.js - 正文解析器无法处理 POST-MAN 表单数据

amazon-web-services - 以编程方式取消对 aws s3 中文件的加密

amazon-web-services - 自动缩放组设置为 0 个实例时的 AWS Codedeploy

javascript - 使用 AngularJS 跟踪和统计点击次数并发布到 MongoDB

javascript - 在 React/Redux 应用程序中,我什么时候应该显式地传递一个 prop,而不是使用 mapStateToProps 从全局状态中获取它?

javascript - "Cannot find global value ' Promise '"Mocha测试出错

amazon-web-services - 如何使用 swagger 和 Rest Api 添加 Lambda 触发器?

javascript - 使用 Ajax 刷新表