Amazon S3 POST api i podpisanie Polityki z NodeJS

Próbuję uzyskać wbudowany, który pozwala użytkownikom przesyłać plik bezpośrednio do mojego wiadra Amazon S3, z witryny NodeJS powered. Wydaje się, że jedyne tutoriale, inne niż rzeczywiste dokumenty amazon dla tego wszystkie są bardzo nieaktualne.

I ' ve been following ten samouczek, dla podstawowych informacji, ale znowu jest przestarzały. Nie posiada wywołań metody crypto correct, ponieważ próbuje przekazać surowy obiekt JavaScript do metody update, która wyrzuca błąd, ponieważ nie jest to łańcuch lub bufor.

Szukałem też źródła dla pakiet knox npm. Nie ma wbudowanej obsługi postów - co całkowicie rozumiem, ponieważ to przeglądarka robi POST, gdy ma odpowiednie pola. Knox wydaje się mieć odpowiedni kod do podpisania polisy, a ja starałem się, aby mój kod działał na tej podstawie... ale znowu bezskutecznie.

Oto, co wymyśliłem, dla kodu. Tworzy baze64 zakodowana polityka i tworzy podpis... ale to zły podpis według Amazon, kiedy próbuję przesłać plik.

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

Najwyraźniej robię coś nie tak. Ale nie mam pojęcia co. Czy ktoś może pomóc zidentyfikować, co robię źle? Gdzie jest mój problem? Czy ktoś ma działający samouczek, Jak wygenerować odpowiednią politykę Amazon S3, z podpisem, z NodeJS v0. 10.x, za POST do S3 REST api?
Author: Derick Bailey, 2013-08-28

3 answers

Ok, w końcu to rozgryzłem. Po bardzo długim czasie gry w Zgadywankę, pomyślałem sobie]}

"może muszę podpisać politykę kodowania base64" - ja

I BAM to było to.

Ponownie zamówiłem warunki, aby pasowały do sposobu zamieszczania formularza, choć nie jestem pewien, czy to robi różnicę.

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

Mam nadzieję, że pomoże to innym, którzy wpadają w ten sam problem.

 34
Author: Derick Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-28 02:03:11

Zmodyfikowałem nieco poprzedni przykład, ponieważ nie działał dla mnie: amazon zwrócił błąd dotyczący zepsutego podpisu.

Oto jak powinien zostać utworzony podpis dla przesyłania w przeglądarce za pomocą POST (AWS Signature Version 4)

Http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html

Obliczanie podpisu

var CryptoJS = require("crypto-js");

var accessKeyID = "PUT YOUR DATA";
var secretAccessKey = "PUT YOUR DATA";

var bucket = "PUT YOUR BUCKET NAME";
var region = "eu-central-1"; // overwrite with your region
var folder = "users/"; // overwrite with your folder
var expiration = "2015-09-28T12:00:00.000Z"; // overwrite date
var date = "20150927"; // overwrite date
var serviceName = "s3";


function getSignatureKey(key, dateStamp, regionName, serviceName) {
   var kDate = CryptoJS.HmacSHA256(dateStamp, "AWS4" + key);
   var kRegion = CryptoJS.HmacSHA256(regionName, kDate);
   var kService = CryptoJS.HmacSHA256(serviceName, kRegion);
   var kSigning = CryptoJS.HmacSHA256("aws4_request", kService);

   return kSigning;
}

var s3Policy = {"expiration": expiration,
  "conditions": [
   {"bucket": bucket},
   ["starts-with", "$key", folder],
   {"acl": "public-read"},
   ["starts-with", "$Content-Type", "image/"],
   {"x-amz-meta-uuid": "14365123651274"},
   ["starts-with", "$x-amz-meta-tag", ""],
   {"x-amz-credential": accessKeyID + "/" + date + "/" + region + "/" + serviceName +"/aws4_request"},
   {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
   {"x-amz-date": date + "T000000Z" }
  ]
};

var base64Policy = new Buffer(JSON.stringify(s3Policy), "utf-8").toString("base64");
console.log('base64Policy:', base64Policy);

var signatureKey = getSignatureKey(secretAccessKey, date, region, serviceName);
var s3Signature = CryptoJS.HmacSHA256(base64Policy, signatureKey).toString(CryptoJS.enc.Hex);
console.log('s3Signature:', s3Signature);

Następnie wygenerowane base64Policy i s3Signature użyłem w formularzu do wgrywania. Przykładem jest proszę.: http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html

Bardzo ważne jest, aby sprawdzić, czy masz te same pola i wartości w formularzu html i w swojej polityce.

 15
Author: scabbiaza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-26 08:49:46

Nadal miałem problemy, więc przejrzałem je i umieściłem moje rozwiązanie tutaj:

Https://github.com/nikkwong/ng2-s3-uploader

W skrócie, jeśli wybierzesz odpowiedź scabbiazy w budowaniu podpisu, upewnij się, że zbudujesz formularz w ten sposób:

let formData = new FormData;
formData.append('acl', xAmzAcl);
formData.append('Content-Type', file.type);
formData.append('X-Amz-Date', xAmzDate);
formData.append('x-amz-server-side-encryption', xAmzServerSideEncryption);
formData.append('x-amz-meta-uuid', xAmzMetaUuid);
formData.append('X-Amz-Algorithm', xAmzAlgorithm);
formData.append('X-Amz-Credential', xAmzCredential);
formData.append('X-Amz-Signature', s3Signature);
formData.append('Policy', base64Policy);
formData.append('key', folder + '/' + file.name);
// File field must come last! 
formData.append('file', file);
 1
Author: nikk wong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-12 08:22:01