18

ユーザーはNodeJSで動くウェブサイトからAmazon S3バケットに直接ファイルをアップロードできるようになりました。 the actual amazon docs for this以外の唯一のチュートリアルは、すべて非常に時代遅れです。Amazon S3 POST api、NodeJSでポリシーに署名する

私は基本情報のためにthis tutorialをフォローしていますが、もう日付が間違っています。 cryptoへのメソッド呼び出しは正しくありません。生のJavaScriptオブジェクトをupdateメソッドに渡そうとするため、文字列やバッファではないためエラーが発生します。

私はまた、the knox npm packageの情報源を探しています。 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); 
}; 

私は明らかに何か間違っています。しかし、私は何が分かりません。誰でも私が間違っていることを特定するのを助けることができますか私の問題はどこですか? NodeJS v0.10.xから、s3 REST APIへのPOST用に、適切なAmazon S3ポリシーを生成するための作業チュートリアルがありますか?

+1

チャンク、自動再開、ユーザーメタデータなどをサポートしたい場合は、特にファイルをS3に直接アップロードするのは簡単なことではありません。私が管理しているライブラリ、[Fine Uploader](http://fineuploader.com)の使用を検討してください。それはすべてのブラウザ(IE7でも)のS3へのダイレクトアップロードをネイティブサポートしています。 Chunkingと自動レジュームもサポートされています。さらに、[Uploader S3]と組み合わせると、あなたのためにすべての署名を処理する[node.jsサーバー側の例](http://bit.ly/1do27a0)を自分で作成しました。 –

+0

このコメントを回答として投稿できますか?私はあなたのライブラリを使用して終了することがあります。それがどのように動作するかなどはまだ評価しています。 –

+1

私はそれがうまくいくかどうかはわかりません。これは貧弱な、またはリンクのみの回答と考えられます。私の理解は、コミュニティがコードを含む詳細な回答を探していて、鉱山がその説明に合致しないということです。それが私がコメントとして投稿した理由です。ファインアップローダーについてご不明な点がございましたら、こちらのファインアップローダータグをご覧ください。ここでは、ライブラリーのサポートに関する質問を処理します。 –

答えて

34

私はついにそれを理解しました。非常に長い時間のために、ランダムな推測ゲームをプレイした後、私は自分自身に

を考えた「たぶん私は、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); 
}; 

これは、同じ問題を抱えている他の人に役立つことを願っています。

+0

感謝します!このコードは私を助けました。いくつかの簡単なコメント:私は[moment.js](http://momentjs.com/docs/)を使って日付をフォーマットしました: 'moment.utc(expirationDate).format( 'YYYY-MM-DD')+ T '+ moment.utc(expirationDate).format(' HH:mm:ss.SSS ')+' Z ''。また、バッファ 'utf8'(注:ハイフンなし)はデフォルトのエンコードであるため、「utf-8」は正しくないと思われます。 – Zugwalt

+4

@ Zugwalt、あなたは瞬時に書式設定されているとかなり単純化することができます。 'moment.utc(expirationDate).toISOString()' – Jonathan

+0

@Jonathanはさらに良い!ありがとう! – Zugwalt

14

私は以前の例を少し変更しました。私にとってはうまくいかなかったからです。アマゾンは壊れた署名についてエラーを返しました。ここ

署名がPOSTを使用して、ブラウザベースのアップロードのために作成されるべきではどのように使用される次のbase64Policyとs3Signatureを生成

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

Calculating a Signature

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

(AWS署名バージョン4)でありますアップロードのためのフォーム。 例: http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html

非常に重要なのは、HTMLフォームとポリシーに同じフィールドと値があることを確認することです。

1

私は問題を抱えているために続けて、私はそれらを介して働いて、ここに私の解決策を掲載:要するに

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

、あなたが署名を構築する上でscabbiazaの答えで行く場合は、フォームを作成することを確認してください

+0

フォームデータに「x-amz-meta-tag」は含まれていません。 –

+1

それはまだ関係なく、私はチェックした。 –

関連する問題