Javascript 如何使用预先签名的URL而不是凭据直接从浏览器上载到AWS S3?
我们希望使用Javascript AWS SDK将文件上载到S3,但根本不使用凭据。 使用凭据上传是可行的,但我们无法为每个应用程序用户生成AWS IAM用户(或者我们应该吗?) 因此,与使用GET类似,我们希望服务器生成一个预签名的URL,将其发送到浏览器,并将浏览器上载到该URL 然而,没有关于如何做到这一点的例子。 此外,如果没有设置凭据,即使在发出上传到S3请求之前,SDK也会出现以下错误:Javascript 如何使用预先签名的URL而不是凭据直接从浏览器上载到AWS S3?,javascript,amazon-web-services,amazon-s3,Javascript,Amazon Web Services,Amazon S3,我们希望使用Javascript AWS SDK将文件上载到S3,但根本不使用凭据。 使用凭据上传是可行的,但我们无法为每个应用程序用户生成AWS IAM用户(或者我们应该吗?) 因此,与使用GET类似,我们希望服务器生成一个预签名的URL,将其发送到浏览器,并将浏览器上载到该URL 然而,没有关于如何做到这一点的例子。 此外,如果没有设置凭据,即使在发出上传到S3请求之前,SDK也会出现以下错误: code: "CredentialsError" message: "No credential
code: "CredentialsError"
message: "No credentials to load"
JS SDK文档提到了这一点,因此似乎有可能:
Pre-signing a putObject (asynchronously)
var params = {Bucket: 'bucket', Key: 'key'};
s3.getSignedUrl('putObject', params, function (err, url) {
console.log('The URL is', url);
});
我可以提出两种方法: 1-您可以在应用程序中生成预签名表单,只需一个凭据 见文件: 2-您可以使用web identity federation并使用google、facebook或amazon登录: 见文件:
游乐场:我更喜欢通过github采用这种更干净的方法: 如果已经为浏览器生成了一个预先签名的URL,那么只需发送一个带有该URL和负载的XHR请求,然后将其上载到S3。SDK不需要这样做。下面是一个jQuery示例:
$.ajax({
url: presignedUrl, // the presigned URL
type: 'PUT',
data: 'data to upload into URL',
success: function() { console.log('Uploaded data successfully.'); }
});
在project中,根据我现在正在做的工作,我将文件从客户端直接上传到S3,在我的例子中,它只需几个步骤即可工作:
它有主要的代码部分:让老问题安静下来,但它确实帮助我最终完成了它。 我的解决方案基于PHP和JavaScript以及jQuery 我已将整个解决方案很好地包装在中,但以下是要点: api.php:
<?php
require_once '/server/path/to/aws-autoloader.php';
use Aws\Common\Aws;
$BUCKET = "my-bucket";
$CONFIG = "path-to-iam-credentials-file-relative-to-root.php"
function getSignedUrl($filename, $mime) {
$S3 = Aws::factory( $CONFIG )->get('S3');
if(!$filename) {
return $this->error('filename missing');
}
if(!$mime) {
return $this->error('mime-type missing');
}
$final_filename = $this->get_file_name($filename);
try {
$signedUrl = $S3->getCommand('PutObject', array(
'Bucket' => $BUCKET,
'Key' => $this->folder . $final_filename,
'ContentType' => $mime,
'Body' => '',
'ContentMD5' => false
))->createPresignedUrl('+30 minutes');
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
$signedUrl .= '&Content-Type='.urlencode($mime);
return $signedUrl;
}
echo getSignedUrl($_GET['filename'],$_GET['mimetype']);
*
得到
邮递
放
头
删除
3000
*
如果您不使用jQuery,这是前端所需的最低限度:
var xhr = new XMLHttpRequest();
xhr.open('PUT', signedUrl, true);
xhr.setRequestHeader('Content-Type', signedUrlContentType);
xhr.onload = () => {
if (xhr.status === 200) {
// success!
}
};
xhr.onerror = () => {
// error...
};
xhr.send(file); // `file` is a File object here
请参阅文件对象文档:
然后,您可以像往常一样添加上载进度:
xhr.upload.onprogress = (event) => {
if (event.lengthComputable) {
var percent = Math.round((event.loaded / event.total) * 100)
console.log(percent);
}
};
请添加
ACL
和ContentType
,它将使其正常工作
const param = {
Bucket: 'Bucket',
Key: 'fiileName',
ACL: 'public-read',
ContentType: 'fileType'
};
s3.getSignedUrl('putObject', param, function (err, url) {
console.log('The URL is', url);
});
生成Url
const AWS = require("aws-sdk");
const s3 = new AWS.S3({
endpoint: 's3-ap-south-1.amazonaws.com', // Put you region
accessKeyId: 'AKXXXXXXXXXXXXXXXA6U', // Put you accessKeyId
secretAccessKey: 'kzFHoXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXssoGp', // Put you accessKeyId
Bucket: 'Bucket-Name', // Put your bucket name
signatureVersion: 'v4',
region: 'ap-south-1' // Put you region
});
const getSingedUrlforPut = async () => {
const params = {
Bucket: 'Bucket-Name',
Key: '317ec11af14a46b89f400bcf8f9fff1222.pdf',
Expires: 60 * 5
};
try {
const url = await new Promise((resolve, reject) => {
s3.getSignedUrl('putObject', params, (err, url) => {
err ? reject(err) : resolve(url);
});
});
console.log(url)
} catch (err) {
if (err) {
console.log(err)
}
}
}
getSingedUrlforPut()
通过ajax上传文件
var form = new FormData();
form.append("", fileInput.files[0], "director_pan_af8ef2d261c46877f95038622c96e7c0.pdf");
var settings = {
"url": "https://sme-testing.s3-ap-south-1.amazonaws.com/317ec11af14a46b89f400bcf8f9fff1222.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIXXXXXXXXXXXX6U%2F20200525%2Fap-south-1%2Fs3%2Faws4_request&X-Amz-Date=20200525T083419Z&X-Amz-Expires=300&X-Amz-Signature=ea063731d7d043b62d0dc7c0984f4d5792c7f7f41e9ffb52a97d62adadcef422&X-Amz-SignedHeaders=host",
"method": "PUT",
"timeout": 0,
"processData": false,
"mimeType": "multipart/form-data",
"contentType": false,
"data": form
};
$.ajax(settings).done(function (response) {
console.log(response);
});
你能再解释一下吗。我的意思是,如果没有AWS S3 SDK,你将如何上传?您需要验证凭据r8?不,您不必验证凭据,因为您在服务器上使用了预签名url(知道您的密钥和秘密)并将此签名url发送到客户端。然后,客户端使用此预签名来上载文件。当我尝试此操作时,我不断得到
[Exception…”对受限URI的访问被拒绝“code:”1012“nsresult:“0x805303f4(NS\u ERROR\u DOM\u BAD\u URI)”位置:“
我假设它与某些CORS策略有关,但目前不知道如何修复它。您是否遇到了此问题?(使用firefox 31.4.0)这里的密钥是什么?此外,如果没有访问ID密钥和机密密钥,您如何向服务器请求已签名的URL?欢迎使用SO。通常会在回答中显示所需代码的最相关部分,以便将搜索保存在web上。尝试了许多不同的方法后,第一次成功。感谢ScottWhat进入get\u file\u name()?
const param = {
Bucket: 'Bucket',
Key: 'fiileName',
ACL: 'public-read',
ContentType: 'fileType'
};
s3.getSignedUrl('putObject', param, function (err, url) {
console.log('The URL is', url);
});
const AWS = require("aws-sdk");
const s3 = new AWS.S3({
endpoint: 's3-ap-south-1.amazonaws.com', // Put you region
accessKeyId: 'AKXXXXXXXXXXXXXXXA6U', // Put you accessKeyId
secretAccessKey: 'kzFHoXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXssoGp', // Put you accessKeyId
Bucket: 'Bucket-Name', // Put your bucket name
signatureVersion: 'v4',
region: 'ap-south-1' // Put you region
});
const getSingedUrlforPut = async () => {
const params = {
Bucket: 'Bucket-Name',
Key: '317ec11af14a46b89f400bcf8f9fff1222.pdf',
Expires: 60 * 5
};
try {
const url = await new Promise((resolve, reject) => {
s3.getSignedUrl('putObject', params, (err, url) => {
err ? reject(err) : resolve(url);
});
});
console.log(url)
} catch (err) {
if (err) {
console.log(err)
}
}
}
getSingedUrlforPut()
var form = new FormData();
form.append("", fileInput.files[0], "director_pan_af8ef2d261c46877f95038622c96e7c0.pdf");
var settings = {
"url": "https://sme-testing.s3-ap-south-1.amazonaws.com/317ec11af14a46b89f400bcf8f9fff1222.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIXXXXXXXXXXXX6U%2F20200525%2Fap-south-1%2Fs3%2Faws4_request&X-Amz-Date=20200525T083419Z&X-Amz-Expires=300&X-Amz-Signature=ea063731d7d043b62d0dc7c0984f4d5792c7f7f41e9ffb52a97d62adadcef422&X-Amz-SignedHeaders=host",
"method": "PUT",
"timeout": 0,
"processData": false,
"mimeType": "multipart/form-data",
"contentType": false,
"data": form
};
$.ajax(settings).done(function (response) {
console.log(response);
});