有没有办法可以生成预签名URL而没有任何到期日期?我正在开发一个电子邮件应用程序,我的附件将保存在S3中.另请告诉我通过JavaScript SDK下载附件的最佳方式是什么.
我正在使用下面的代码
var params = {Bucket: 'bucket', Key: 'key', Expires: 60};
var url = s3.getSignedUrl('getObject', params);
console.log('The URL is', url);
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用签名的URL将图像上传到s3存储桶.以下是我的保管政策:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::12345678:user/myuser",
"arn:aws:iam::12345678:root"
]
},
"Action": [
"s3:List*",
"s3:Put*",
"s3:Get*"
],
"Resource": [
"arn:aws:s3:::myBucket",
"arn:aws:s3:::myBucket/*"
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
我从服务器生成签名的URL如下:
var aws = require('aws-sdk');
aws.config = {
accessKeyId: myAccessKeyId,
secretAccessKey: mySecretAccessKey
};
var s3 = new aws.s3();
s3.getSignedUrl('putObject', {
Bucket: 'myBucket',
Expires: 60*60,
key: 'myKey'
}, function (err, url) {
console.log(url);
});
Run Code Online (Sandbox Code Playgroud)
我得到了网址.但是当我尝试放置一个对象时,我收到以下错误:
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>FXXXXXXXXX</RequestId>
<HostId>fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</HostId>
</Error>
Run Code Online (Sandbox Code Playgroud)
更新1
这是myuser的政策:
{
"Version": "2012-10-17",
"Statement": …
Run Code Online (Sandbox Code Playgroud) javascript amazon-s3 amazon-web-services node.js pre-signed-url
是否有人成功使用AWS SDK生成S3存储桶中对象的签名URL,这些URL也可以在CloudFront上运行?我正在使用JavaScript AWS SDK,通过S3链接生成签名URL非常简单.我刚刚创建了一个私有存储桶并使用以下代码生成URL:
var AWS = require('aws-sdk')
, s3 = new AWS.S3()
, params = {Bucket: 'my-bucket', Key: 'path/to/key', Expiration: 20}
s3.getSignedUrl('getObject', params, function (err, url) {
console.log('Signed URL: ' + url)
})
Run Code Online (Sandbox Code Playgroud)
这很好但我也希望向用户公开CloudFront URL,以便他们可以获得使用CDN的更高下载速度.我设置了一个CloudFront发行版,它修改了存储桶策略以允许访问.但是,执行此操作后,任何文件都可以通过CloudFront URL访问,而亚马逊似乎忽略了我的链接中的签名.在阅读了更多内容后,我发现有人生成一个.pem文件来获取使用CloudFront的签名URL,但为什么S3不需要这样做?似乎getSignedUrl方法只使用AWS Secret Key和AWS Access Key进行签名.有没有人得到过这样的设置呢?
更新: 经过进一步研究后,CloudFront似乎处理的URL签名完全不同于S3 [link].但是,我仍然不清楚如何使用Javascript创建签名的CloudFront URL.
javascript amazon-s3 amazon-web-services node.js pre-signed-url
请考虑以下代码:
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("text/plain; charset=utf-8"); // [A]
RequestBody body = RequestBody.create(mediaType, media);
String[] aclHeader = "x-goog-acl:public-read".split(":");
Request request = new Request.Builder()
.addHeader("Content-Type", "text/plain") // [B]
.addHeader(aclHeader[0], aclHeader[1])
.url(url)
.put(body)
.build();
Response response = client.newCall(request).execute();
Run Code Online (Sandbox Code Playgroud)
我从客户端访问GCS,并使用以前签名的URL.
问题:似乎okhttp将为身体[A]声明的字符集添加到URL中(至少对于text/plain),即使它未在[B]中声明.这会弄乱我签名的URL,GCS会返回403 Forbidden.
但这不是应该的.至少在使用签名URL时,必须将这些URL完全按照声明的方式发送到服务器.
我尝试使用Apache http客户端(我不想在生产中使用,因为okhttpclient已经是我的安装的一部分)并且该客户端不会暴露这种行为:
String[] aclHeader = "x-goog-acl:public-read".split(":");
StatusLine statusLine = Request
.Put(url)
.addHeader("Content-Type", "text/plain")
.addHeader(aclHeader[0], aclHeader[1])
.bodyByteArray(media)
.execute().returnResponse().getStatusLine();
Run Code Online (Sandbox Code Playgroud)
有没有办法抑制okhttp中的行为,它是添加到Content-Type还是冗余地传输了Body-Type中的Content-Type?
根据这个链接http://docs.aws.amazon.com/aws-sdk-php/v2/guide/service-s3.html,我可以轻松地创建一个预先指定的链接,只需将生命周期添加到getObjectUrl
$signedUrl = $client->getObjectUrl($bucket, 'data.txt', '+10 minutes');
// > https://my-bucket.s3.amazonaws.com/data.txt?AWSAccessKeyId=[...]&Expires=[...]&Signature=[...]
Run Code Online (Sandbox Code Playgroud)
但是我得到一个简单的URL,你知道,没有awsaccesskeyid和expires参数,
这是我的代码:
$bucket = 'imagenesfc';
$keyname = 'NASimagenes/codigoBarraBoleto/1001000098.png';
$filepath = 'NASimagenes/codigoBarraBoleto';
// Instantiate the client.
$s3 = S3Client::factory(array(
'version' => 'latest',
'region' => 'us-west-1'
));
$signedUrl = $s3->getObjectUrl($bucket, $keyname,'+10 minutes');
// > https://my-bucket.s3.amazonaws.com/data.txt?AWSAccessKeyId=[...]&Expires=[...]&Signature=[...]
echo $signedUrl."<br>";
Run Code Online (Sandbox Code Playgroud)
编辑:我有AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY作为环境变量
我的回声看起来像:
https://s3-us-west-1.amazonaws.com/imagenesfc/NASimagenes/codigoBarraBoleto/1001000098.png
怎么了?
尝试使用预先签名的URL从React Native上传图像到没有运气.这是我的代码:
在节点中生成预先签名的URL:
const s3 = new aws.S3();
const s3Params = {
Bucket: bucket,
Key: fileName,
Expires: 60,
ContentType: 'image/jpeg',
ACL: 'public-read'
};
return s3.getSignedUrl('putObject', s3Params);
Run Code Online (Sandbox Code Playgroud)
这是对S3的RN请求:
var file = {
uri: game.pictureToSubmitUri,
type: 'image/jpeg',
name: 'image.jpg',
};
const xhr = new XMLHttpRequest();
var body = new FormData();
body.append('file', file);
xhr.open('PUT', signedRequest);
xhr.onreadystatechange = () => {
if(xhr.readyState === 4){
if(xhr.status === 200){
alert('Posted!');
}
else{
alert('Could not upload file.');
}
}
};
xhr.send(body);
Run Code Online (Sandbox Code Playgroud)
game.pictureToSubmitUri = assets-library://asset/asset.JPG?id=A282A2C5-31C8-489F-9652-7D3BD5A1FAA4&ext=JPG
signedRequest = https://my-bucket.s3-us-west-1.amazonaws.com/8bd2d4b9-3206-4bff-944d-e06f872d8be3?AWSAccessKeyId=AKIAIOLHQY4GAXN26FOQ&Content-Type=image%2Fjpeg&Expires=1465671117&Signature=bkQIp5lgzuYrt2vyl7rqpCXPcps%3D&x-amz-acl=public-read …
xmlhttprequest amazon-s3 amazon-web-services pre-signed-url react-native
目标
我们希望用户能够将图像上传到 Google Cloud Storage。
问题
我们可以通过我们的服务器作为中间人间接实现这一点——首先,用户上传到我们的服务器,然后我们的特权服务器可以上传到 Cloud Storage。
但是,我们认为这不必要地慢,而是希望用户直接上传到 Cloud Storage。
建议的解决方案
为了实现直接上传,我们在我们的服务器上生成一个签名 URL。签名 URL 指定过期时间,并且只能与 HTTP PUT 动词一起使用。用户可以请求签名 URL,然后 - 仅在有限的时间内 - 将图像上传到签名 URL 指定的路径。
解决方案的问题
有没有办法强制最大文件上传大小?显然,当我们期望 <1MB 文件时,我们希望避免用户尝试上传 20GB 文件。
看起来这是一个明显的漏洞,但我不知道如何在仍然使用 SignedURL 的同时解决它。
似乎有一种方法可以使用 Policy Documents ( Stack Overflow answer )来做到这一点,但这个问题现在已经超过 2 年了。
upload http google-cloud-storage pre-signed-url google-cloud-platform
我正在使用 PHP 开发 Web 应用程序。在我的应用程序中,我需要使用预签名 URL 将文件上传到 AWS S3 存储桶。现在,我可以使用这样的预签名从 S3 存储桶中读取私有文件。
$s3Client = new S3Client([
'version' => 'latest',
'region' => env('AWS_REGION', ''),
'credentials' => [
'key' => env('AWS_IAM_KEY', ''),
'secret' => env('AWS_IAM_SECRET', '')
]
]);
//GetObject
$cmd = $s3Client->getCommand('GetObject', [
'Bucket' => env('AWS_BUCKET',''),
'Key' => 'this-is-uploaded-using-presigned-url.png'
]);
$request = $s3Client->createPresignedRequest($cmd, '+20 minutes');
//This is for reading the image. It is working.
$presignedUrl = (string) $request->getUri();
Run Code Online (Sandbox Code Playgroud)
当我$presignedUrl
从浏览器访问时,我可以从 s3 获取文件。这是工作。但是现在,我正在将文件上传到 S3。不从 s3 读取文件。通常,我可以像这样将文件上传到 S3。
$client->putObject(array(
'Bucket' => $bucket,
'Key' …
Run Code Online (Sandbox Code Playgroud) 我试图使用alamofire直接上传到s3(我的应用程序必须在苹果手表上运行,而aws-ios-sdk在Apple手表上不起作用).我知道我必须在网址上签名,但我不知道如何直接形成网址请求.但是,我目前的做法似乎没有那种做法.我发现了几个类似的问题,似乎没有解决上传与alamofire直接到s3,端到端,包括签署一个带访问密钥和秘密的URL.
class UploadUtil
public func upload(file: URL, key: String, success: @escaping ()->()) {
let access_key = "AKIA123453435242"
let secret = "abcdefghijklmnopqrstuvwxyz"
Alamofire.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(unicornImageURL, withName: "unicorn")
multipartFormData.append(rainbowImageURL, withName: "rainbow")
},
to: "https://mybucket.s3.amazonaws.com",
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}
}
)
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个 S3 存储桶,其中包含 PDF 文件作为对象,并且所有文件都是私有的。我以编程方式创建一个 S3 预签名 URL 来获取该对象。效果很好。现在,我希望它可以以 PDF 形式预览。每个对象都已经有一个Content-Type
设置为 的标头application/pdf
。现在,如果我将response-content-disposition
标头设置为查询参数,它会被设置但不会覆盖已经存在的Content-disposition
标头,而是创建一个新标头。如果我Content-Disposition
在 S3 对象的元数据中设置标头,而不是将其作为查询参数添加到 S3 预签名 URL 中,它仍然显示 2 个标头。这是 AWS S3 端的某种错误吗?
以下是响应标头的屏幕截图以供参考。
任何帮助都感激不尽。谢谢。
amazon-s3 content-disposition amazon-web-services node.js pre-signed-url
pre-signed-url ×10
amazon-s3 ×8
node.js ×3
javascript ×2
php ×2
alamofire ×1
http ×1
java ×1
okhttp ×1
react-native ×1
upload ×1