18

के साथ पॉलिसी पर हस्ताक्षर करना मैं एक ऐसा निर्माण करने की कोशिश कर रहा हूं जो उपयोगकर्ताओं को सीधे मेरे अमेज़ॅन एस 3 बाल्टी में एक नोडजेएस संचालित वेबसाइट से फ़ाइल अपलोड करने की अनुमति दे। ऐसा लगता है कि the actual amazon docs for this के अलावा, यह बहुत ही पुराना ट्यूटोरियल है।अमेज़ॅन एस 3 पोस्ट एपीआई, और नोडजेएस

मैं निम्नलिखित जानकारी के लिए this tutorial का पालन कर रहा हूं, लेकिन फिर से यह दिनांक समाप्त हो गया है। इसमें crypto सही तरीके से विधि नहीं है, क्योंकि यह update विधि पर एक कच्ची जावास्क्रिप्ट ऑब्जेक्ट पास करने का प्रयास करता है, जो त्रुटि उत्पन्न करता है क्योंकि यह स्ट्रिंग या बफर नहीं है।

मैं the knox npm package के स्रोत को भी देख रहा हूं। इसमें पोस्ट समर्थन नहीं है - जिसे मैं पूरी तरह से समझता हूं, क्योंकि ब्राउजर सही क्षेत्र में एक बार पोस्ट कर रहा है। नोक्स में नीति पर हस्ताक्षर करने का सही कोड प्रतीत होता है, और मैंने इस पर आधारित अपना कोड काम करने की कोशिश की है ... लेकिन फिर से कोई फायदा नहीं हुआ।

कोड के लिए मैं यहां आया हूं। यह बेस 64 एन्कोडेड नीति बनाता है, और यह एक हस्ताक्षर बनाता है ... लेकिन जब मैं फ़ाइल अपलोड करने का प्रयास करता हूं तो यह अमेज़ॅन के अनुसार गलत हस्ताक्षर है।


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

मैं स्पष्ट रूप से कुछ गलत कर रहा हूं। लेकिन मुझे नहीं पता कि क्या। क्या कोई यह पहचानने में मदद कर सकता है कि मैं क्या गलत कर रहा हूं? मेरी समस्या कहां है? क्या किसी के पास S3 REST api पर पोस्ट के लिए, NodeJS v0.10.x से, हस्ताक्षर के साथ, उचित अमेज़ॅन S3 नीति उत्पन्न करने के लिए एक ट्यूटोरियल ट्यूटोरियल है?

+1

S3 के लिए सीधे कोई फ़ाइल अपलोड करने नहीं वास्तव में एक छोटी सी कार्य स्वत: फिर से शुरू, उपयोगकर्ता मेटाडाटा, आदि, आदि नीति सामान काफी जटिल हो _can_ है, खासकर यदि आप बेडौल समर्थन करना चाहते हैं,। एक लाइब्रेरी का उपयोग करने पर विचार करें जो मैं बनाए रखता हूं: [ठीक अपलोडर] (http://fineuploader.com)। यह सभी ब्राउज़रों में एस 3 पर प्रत्यक्ष अपलोड के लिए देशी समर्थन है, यहां तक ​​कि आईई 7 भी। चंकिंग और ऑटो-रेज़्यूमे, अन्य सुविधाओं के साथ भी समर्थित हैं। इसके अलावा, मैंने एक [node.js सर्वर-साइड उदाहरण] (http://bit.ly/1do27a0) लिखा है कि, जब ठीक अपलोडर एस 3 के साथ जोड़ा गया है, तो आपके लिए सभी हस्ताक्षरों को संभालेगा। –

+0

क्या आप इस टिप्पणी को उत्तर के रूप में पोस्ट कर सकते हैं? मैं आपकी लाइब्रेरी का उपयोग कर समाप्त कर सकता हूं। अभी भी मूल्यांकन करता है कि यह कैसे काम करता है, आदि –

+1

मुझे यकीन नहीं है कि यह अच्छी तरह से खत्म हो जाएगा। इसे एक गरीब या लिंक-केवल उत्तर माना जा सकता है, बिल्कुल स्पष्ट रूप से। मेरी समझ यह है कि समुदाय विवरण के उत्तरों की तलाश में है जिसमें कोड शामिल है, और मेरा वह विवरण फिट नहीं है, इसलिए मैंने इसे एक टिप्पणी के रूप में पोस्ट किया है। यदि आपके पास ठीक अपलोडर के बारे में कोई प्रश्न है, तो SO पर ठीक-अपलोडर टैग पर एक नज़र डालें, जहां हम लाइब्रेरी के लिए समर्थन प्रश्नों को संभालते हैं। –

उत्तर

34

ठीक है, मैंने अंततः इसे समझ लिया। एक बहुत लंबे समय के लिए यादृच्छिक अनुमान लगा खेल खेलने के बाद, मैंने सोचा कि करने के लिए अपने आप को

"शायद मैं बेस 64 इनकोडिंग नीति पर हस्ताक्षर करने की जरूरत है" - मुझे

और 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 (समाप्ति दिनांक) .format ('YYYY-MM-DD') + ' टी '+ moment.utc (ExpirationDate) .format (' HH: mm: ss.SSS ') +' Z''। बफर 'utf8' के लिए भी (नोट: कोई हाइफ़न) डिफ़ॉल्ट एन्कोडिंग नहीं है, इसलिए मुझे लगता है कि "utf-8" गलत और अपरिपक्व है। – Zugwalt

+4

@ ज़ुगवाल्ट, आप फ़ॉर्मेटिंग में बने पल के साथ थोड़ा सा सरल बना सकते हैं। 'moment.utc (समाप्ति दिनांक) .toISOString()' – Jonathan

+0

@ जोनाथन भी बेहतर! धन्यवाद! – Zugwalt

14

मैंने थोड़ा पिछले उदाहरण संशोधित किया, क्योंकि यह मेरे लिए काम नहीं करता था: अमेज़ॅन टूटा हस्ताक्षर के बारे में एक त्रुटि लौटा दी।

यहाँ (एडब्ल्यूएस हस्ताक्षर संस्करण 4)

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

अगला उत्पन्न base64Policy और s3Signature मैं में इस्तेमाल हस्ताक्षर ब्राउज़र आधारित अपलोड पोस्ट का उपयोग के लिए बनाया जाना चाहिए कि कैसे है अपलोड करने के लिए फॉर्म। उदाहरण यहां है: http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html

यह जांचना बहुत महत्वपूर्ण है कि आपके पास HTML फॉर्म और आपकी नीति में समान फ़ील्ड और मान हैं।

1

मैं मुद्दे के लिए जारी रखा, तो मैं उन के माध्यम से काम किया है और मेरी समाधान यहां पोस्ट:

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

संक्षेप में, यदि आप हस्ताक्षर के निर्माण में scabbiaza के जवाब के साथ जाना है, प्रपत्र का निर्माण करने के लिए सुनिश्चित करें जैसे इतना:

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

आपके फॉर्म डेटा में "x-amz-meta-tag" शामिल नहीं है। –

+1

यह अभी भी काम करेगा, मैंने अभी जांच की है। –