gpt4 book ai didi

javascript - 如何使用预签名 URL 而不是凭证直接从浏览器上传到 AWS S3?

转载 作者:行者123 更新时间:2023-12-03 00:04:12 38 4
gpt4 key购买 nike

我们希望使用 Javascript AWS SDK 将文件上传到 S3,但根本不使用凭证。使用凭证上传是可行的,但我们无法为每个应用程序用户生成 AWS IAM 用户(或者我们应该吗?)

因此,与使用 GET 类似,我们希望服务器生成预签名 URL,将其发送到浏览器,然后让浏览器上传到该 URL。

但是,没有关于如何实现此目的的示例。此外,如果未设置凭据,即使在发出上传到 S3 请求之前,SDK 也会出现错误

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

最佳答案

平息这个老问题,但它确实帮助我最终完成了它。我的解决方案基于 PHP 和 JavaScript 以及 jQuery。

我将整个解决方案很好地包装在 https://github.com/JoernBerkefeld/s3SignedUpload但以下是要点:

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

请确保将添加用户身份验证到您的 api.php。否则,知道该文件路径的每个人都可以将文件上传到您的存储桶。

credentials.inc.php:

<?php
return array(
'includes' => array('_aws'),
'services' => array(
'default_settings' => array(
'params' => array(
'key' => 'MY-ACCESS-KEY',
'secret' => 'MY-SECRECT',
'region' => 'eu-west-1' // set to your region
)
)
)
);

客户端.js:

$("input[type=file]").onchange = function () {
for (var file, i = 0; i < this.files.length; i++) {
file = this.files[i];
$.ajax({
url : s3presignedApiUri,
data: 'file='+ file.name + '&mime=' + file.type,
type : "GET",
dataType : "json",
cache : false,
})
.done(function(s3presignedUrl) {
$.ajax({
url : s3presignedUrl,
type : "PUT",
data : file,
dataType : "text",
cache : false,
contentType : file.type,
processData : false
})
.done(function(){
console.info('YEAH', s3presignedUrl.split('?')[0].substr(6));
}
.fail(function(){
console.error('damn...');
}
})
}
};

s3 cors设置(实际上需要PUT & OPTIONS,但不能直接启用OPTIONS...):

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

关于javascript - 如何使用预签名 URL 而不是凭证直接从浏览器上传到 AWS S3?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22531114/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com