![](/img/trans.png)
[英]Node.js and the connect module: How do I get the message out of a request object sent to a web server
[英]How do I get the node.js server to sign the request from amazon web services for fine uploader?
嘗試將映像上傳到AWS時,讓node.js從AWS簽名請求時遇到問題。 這是我在Chrome控制台中看到的內容:
[Fine Uploader 4.4.0] Parsing template s3.jquery.fineuploader-4.4.0.js:198
[Fine Uploader 4.4.0] Template parsing complete s3.jquery.fineuploader-4.4.0.js:198
[Fine Uploader 4.4.0] Rendering template in DOM. s3.jquery.fineuploader-4.4.0.js:198
[Fine Uploader 4.4.0] Template rendering complete s3.jquery.fineuploader-4.4.0.js:198
[Fine Uploader 4.4.0] Received 1 files or inputs. s3.jquery.fineuploader-4.4.0.js:198
[Fine Uploader 4.4.0] Attempting to validate image. s3.jquery.fineuploader-4.4.0.js:198
[Fine Uploader 4.4.0] Submitting S3 signature request for 0 s3.jquery.fineuploader-4.4.0.js:198
[Fine Uploader 4.4.0] Sending POST request for 0 s3.jquery.fineuploader-4.4.0.js:198
OPTIONS file://192.168.2.16/fine-uploader/_dist/s3/server.js No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. s3.jquery.fineuploader-4.4.0.js:3657
XMLHttpRequest cannot load file://192.168.2.16/fine-uploader/_dist/s3/server.js. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. default.html:1
[Fine Uploader 4.4.0] POST request for 0 has failed - response code 0 s3.jquery.fineuploader-4.4.0.js:203
[Fine Uploader 4.4.0] Received an empty or invalid response from the server! s3.jquery.fineuploader-4.4.0.js:203
[Fine Uploader 4.4.0] Policy signing failed. Received an empty or invalid response from the server! s3.jquery.fineuploader-4.4.0.js:203
[Fine Uploader 4.4.0] Received response status 0 with body: s3.jquery.fineuploader-4.4.0.js:198
我意識到我對簽名做錯了事,但是由於文檔不清楚,我不知道下一步該怎么做。 這是我的HTML,server.js和CORS:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery-1.10.2.js" type="text/javascript"> </script>
<link href="../../s3/fineuploader-4.4.0.min.css" rel="stylesheet">
<script src="../../s3/s3.jquery.fineuploader-4.4.0.js"></script>
<script>
// Wait until the DOM is 'ready'
$(document).ready(function () {
$("#fine-uploader").fineUploaderS3({
debug: true,
request: {
endpoint: 'fineuploader1.s3.amazonaws.com'
// accessKey: 'AKIAICPB2GGIC4VOF2WQ'
},
signature: {
endpoint: '../../s3/server.js'
},
uploadSuccess: {
endpoint: '/s3/success'
},
iframeSupport: {
localBlankPagePath: '/success.html'
},
retry: {
enableAuto: true // defaults to false
},
deleteFile: {
enabled: true,
endpoint: '/s3handler'
}
});
});
</script>
<script type="text/template" id="qq-template">
<div class="qq-uploader-selector qq-uploader">
<div class="qq-total-progress-bar-container-selector qq-total-progress-bar-container">
<div class="qq-total-progress-bar-selector qq-progress-bar qq-total-progress-bar"></div>
</div>
<div class="qq-upload-drop-area-selector qq-upload-drop-area" qq-hide-dropzone>
<span>Drop files here to upload</span>
</div>
<div class="qq-upload-button-selector qq-upload-button">
<div>Upload a file</div>
</div>
<span class="qq-drop-processing-selector qq-drop-processing">
<span>Processing dropped files...</span>
<span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>
</span>
<ul class="qq-upload-list-selector qq-upload-list">
<li>
<div class="qq-progress-bar-container-selector">
<div class="qq-progress-bar-selector qq-progress-bar"></div>
</div>
<span class="qq-upload-spinner-selector qq-upload-spinner"></span>
<span class="qq-edit-filename-icon-selector qq-edit-filename-icon"></span>
<span class="qq-upload-file-selector qq-upload-file"></span>
<input class="qq-edit-filename-selector qq-edit-filename" tabindex="0" type="text">
<span class="qq-upload-size-selector qq-upload-size"></span>
<a class="qq-upload-cancel-selector qq-upload-cancel" href="#">Cancel</a>
<a class="qq-upload-retry-selector qq-upload-retry" href="#">Retry</a>
<a class="qq-upload-delete-selector qq-upload-delete" href="#">Delete</a>
<span class="qq-upload-status-text-selector qq-upload-status-text"></span>
</li>
</ul>
</div>
</script>
<title>Fine Uploader default UI</title>
</head>
<body>
<div id="fine-uploader"></div>
</body>
</html>
server.js:
var express = require("express"),
crypto = require("crypto"),
aws = require("aws-sdk"),
app = express(),
clientSecretKey = process.env.CLIENT_SECRET_KEY,
// These two keys are only needed if you plan on using the AWS SDK
serverPublicKey = process.env.SERVER_PUBLIC_KEY,
serverSecretKey = process.env.SERVER_SECRET_KEY,
// Set these two values to match your environment
expectedBucket = "fineuploadertest1",
expectedMaxSize = 15000000,
s3;
// Init S3, given your server-side keys. Only needed if using the AWS SDK.
aws.config.update({
accessKeyId: serverPublicKey,
secretAccessKey: serverSecretKey
});
s3 = new aws.S3();
app.use(express.bodyParser());
app.use(express.static(__dirname)); //only needed if serving static content as well
app.listen(8000);
// Handles all signature requests and the success request FU S3 sends after the file is in S3
// You will need to adjust these paths/conditions based on your setup.
app.post("\\192.168.2.16\fine-uploader\_dist\s3\server.js", function(req, res) {
if (req.query.success !== undefined) {
verifyFileInS3(req, res);
}
else {
signRequest(req, res);
}
});
// Handles the standard DELETE (file) request sent by Fine Uploader S3.
// Omit if you don't want to support this feature.
app.delete("../../s3/server.js", function(req, res) {
deleteFile(req.query.bucket, req.query.key, function(err) {
if (err) {
console.log("Problem deleting file: " + err);
res.status(500);
}
res.end();
});
});
// Signs any requests. Delegate to a more specific signer based on type of request.
function signRequest(req, res) {
if (req.body.headers) {
signRestRequest(req, res);
}
else {
signPolicy(req, res);
}
}
// Signs multipart (chunked) requests. Omit if you don't want to support chunking.
function signRestRequest(req, res) {
var stringToSign = req.body.headers,
signature = crypto.createHmac("sha1", clientSecretKey)
.update(stringToSign)
.digest("base64");
var jsonResponse = {
signature: signature
};
res.setHeader("Content-Type", "application/json");
if (isValidRestRequest(stringToSign)) {
res.end(JSON.stringify(jsonResponse));
}
else {
res.status(400);
res.end(JSON.stringify({invalid: true}));
}
}
// Signs "simple" (non-chunked) upload requests.
function signPolicy(req, res) {
var base64Policy = new Buffer(JSON.stringify(req.body)).toString("base64"),
signature = crypto.createHmac("sha1", clientSecretKey)
.update(base64Policy)
.digest("base64");
var jsonResponse = {
policy: base64Policy,
signature: signature
};
res.setHeader("Content-Type", "application/json");
if (isPolicyValid(req.body)) {
res.end(JSON.stringify(jsonResponse));
}
else {
res.status(400);
res.end(JSON.stringify({invalid: true}));
}
}
// Ensures the REST request is targeting the correct bucket.
// Omit if you don't want to support chunking.
function isValidRestRequest(headerStr) {
return new RegExp("\/" + expectedBucket + "\/.+$").exec(headerStr) != null;
}
// Ensures the policy document associated with a "simple" (non-chunked) request is
// targeting the correct bucket and the max-size is as expected.
// Omit the parsedMaxSize-related code if you don't have a max file size.
function isPolicyValid(policy) {
var bucket, parsedMaxSize;
policy.conditions.forEach(function(condition) {
if (condition.bucket) {
bucket = condition.bucket;
}
else if (condition instanceof Array && condition[0] === "content-length-range") {
parsedMaxSize = condition[2];
}
});
return bucket === expectedBucket && parsedMaxSize === expectedMaxSize.toString();
}
// After the file is in S3, make sure it isn't too big.
// Omit if you don't have a max file size, or add more logic as required.
function verifyFileInS3(req, res) {
function headReceived(err, data) {
if (err) {
res.status(500);
console.log(err);
res.end(JSON.stringify({error: "Problem querying S3!"}));
}
else if (data.ContentLength > expectedMaxSize) {
res.status(400);
res.write(JSON.stringify({error: "Too big!"}));
deleteFile(req.body.bucket, req.body.key, function(err) {
if (err) {
console.log("Couldn't delete invalid file!");
}
res.end();
});
}
else {
res.end();
}
}
callS3("head", {
bucket: req.body.bucket,
key: req.body.key
}, headReceived);
}
function deleteFile(bucket, key, callback) {
callS3("delete", {
bucket: bucket,
key: key
}, callback);
}
function callS3(type, spec, callback) {
s3[type + "Object"]({
Bucket: spec.bucket,
Key: spec.key
}, callback)
}
CORS:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<ExposeHeader>ETag</ExposeHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
因此,根據文檔http://docs.fineuploader.com/quickstart/03-setting_up_server-s3.html的說明 ,我將通過下載並運行服務器來設置服務器。 但是,它沒有提及簽名。 我將簽名指向server.js。 我不知道還有什么要指出的。 此頁面上有關簽名的文檔http://docs.fineuploader.com/endpoint_handlers/amazon-s3.html似乎對我完全沒有幫助,因為我不理解它在試圖使我做什么。讓它起作用。 我知道這些可能是愚蠢的問題,但我只需要指出正確的方向,這樣我就可以繼續前進。 我非常感謝您的幫助。 非常感謝。 如果可以提供更多信息,請告訴我。
首先,我猜您沒有在服務器中設置CLIENT_SECRET_KEY環境變量的屬性。 應將其設置為與在上載程序的構建過程中傳遞給Fine Uploader S3的公用密鑰相對應的同一IAM用戶的私鑰。
其次,您應該從適當的Web服務器提供頁面。 我可以從日志消息中得知您沒有這樣做。
第三,為什么要在JavaScript選項中注釋掉訪問密鑰? 這是必需的選項。
您的設置可能還有其他問題,但是乍一看,這些是最明顯的問題。 只要正確設置服務器和客戶端,提供的節點示例就可以正常工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.