在本文中,我们将带你了解如何在Go中将预签名的POST上传到AWSS3?在这篇文章中,同时我们还将给您一些技巧,以帮助您实现更有效的ios–使用预签名URL将文件上传到AWSS3的代码有什么问题?、i
在本文中,我们将带你了解如何在Go中将预签名的POST上传到AWS S3?在这篇文章中,同时我们还将给您一些技巧,以帮助您实现更有效的ios – 使用预签名URL将文件上传到AWS S3的代码有什么问题?、iOS – 同步上传到AWS S3、java-使用Retrofit2将文件上传到AWS S3预签名URL、javascript – 如何使用Meteor将文件上传到Amazon S3?。
本文目录一览:- 如何在Go中将预签名的POST上传到AWS S3?
- ios – 使用预签名URL将文件上传到AWS S3的代码有什么问题?
- iOS – 同步上传到AWS S3
- java-使用Retrofit2将文件上传到AWS S3预签名URL
- javascript – 如何使用Meteor将文件上传到Amazon S3?
如何在Go中将预签名的POST上传到AWS S3?
我想执行一个预签名的POST以将文件上传到AWSS3存储桶-如何在Go中完成?
请注意,这与通过PUT进行预签名上传不同。
答案1
小编典典因此,为了帮助他人,我将自己回答问题,并提供一些代码来帮助可能遇到相同问题的其他人。
可在此处找到Google App Engine呈现预签名POST表单的示例网络应用。
和一个小型图书馆,我创建做在Go预签POST。
简而言之,对公共读取的Amazon S3存储桶执行预签名的POST,您需要:
1.将S3存储桶配置为仅允许公共下载。
仅允许公共读取的示例存储桶策略。
{ "Version": "2012-10-17", "Id": "akjsdhakshfjlashdf", "Statement": [ { "Sid": "kjahsdkajhsdkjasda", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::BUCKETNAMEHERE/*" } ]}
2.为允许上传的HTTP POST创建一个策略。
AWSS3文档
示例POST策略模板,带有过期时间,可以将特定密钥上载到特定存储桶中,并允许公众读取访问。
{ "expiration": "%s", "conditions": [ {"bucket": "%s"}, ["starts-with", "$key", "%s"], {"acl": "public-read"}, {"x-amz-credential": "%s"}, {"x-amz-algorithm": "AWS4-HMAC-SHA256"}, {"x-amz-date": "%s" } ]}
3.使用S3存储桶所有者的凭据生成并签名策略。
AWS文档
- 填写正确的值以表示到期时间,存储段,密钥,凭据和日期。
- base64对策略进行编码。
- HMAC-SHA256获取签名的策略。
- 十六进制编码签名。
4.构造并发布多部分表单数据
AWS S3文档
现在,您要么生成HTML表单,然后自动获取正确的多部分表单数据请求,如上面的链接中所述。
我想在Go中手动完成此操作,所以这里是操作方法。
无论哪种方式,您都需要提供在步骤2和3中创建的POST策略中指定的所有部分。请求中除了强制性字段(策略中不包含)外,也不能有其他字段。
还指定了字段的顺序,并且它们都是HTTP POST请求中的多部分字段。
func Upload(url string, fields Fields) error { var b bytes.Buffer w := multipart.NewWriter(&b) for _, f := range fields { fw, err := w.CreateFormField(f.Key) if err != nil { return err } if _, err := fw.Write([]byte(f.Value)); err != nil { return err } } w.Close() req, err := http.NewRequest("POST", url, &b) if err != nil { return err } req.Header.Set("Content-Type", w.FormDataContentType()) client := &http.Client{} res, err := client.Do(req) if err != nil { return err } if res.StatusCode != http.StatusOK { err = fmt.Errorf("bad status: %s", res.Status) } return nil}
ios – 使用预签名URL将文件上传到AWS S3的代码有什么问题?
curl -v -k --upload-file FILENAME "https://MYBUCKET.amazonaws.com:443/KEYNAME?Signature=...&Expires=1391691489&AWSAccessKeyId=..."
使用以下Objective-C代码……
- (void)upload:(Nsstring *)url fileData:(NSData *)fileData { NSMutableuRLRequest *request = [[NSMutableuRLRequest alloc] init]; [request setURL:[NSURL URLWithString:url]]; [request setHTTPMethod:@"PUT"]; [request setHTTPBody:fileData]; [request setValue:[Nsstring stringWithFormat:@"%d",[fileData length]] forHTTPHeaderField:@"Content-Length"]; [request setValue:@"audio/mpeg" forHTTPHeaderField:@"Content-Type"]; [request setValue:@"public-read" forHTTPHeaderField:@"x-amz-acl"]; [request setValue:@"iPhone-OS/6.0 fr_FR NE" forHTTPHeaderField:@"User-Agent"]; _connection = [NSURLConnection connectionWithRequest:request delegate:self]; [_connection start]; }
…我收到此错误:
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0x9c49560 {NSErrorFailingURLStringKey=https://MYBUCKET.s3.amazonaws.com:443/KEYNAME?Signature=...&Expires=1391703958&AWSAccessKeyId=...,NSErrorFailingURLKey=https://MYBUCKET.amazonaws.com:443/KEYNAME?Signature=...&Expires=1391703958&AWSAccessKeyId=...,NSLocalizedDescription=The request timed out.,NSUnderlyingError=0x9c48c80 "The request timed out."}
我使用WireShark查看是否有任何流量,并且流量很大.
我不知道我的代码有什么问题.似乎文件传输没有正确终止.
解决方法
<?xml version="1.0" encoding="UTF-8"?> <Error> <Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><StringToSignBytes>...</StringToSignBytes><RequestId>...</RequestId><HostId>...</HostId><SignatureProvided>...</SignatureProvided> <StringToSign>PUT text/plain 1391784394 KEYNAME</StringToSign> <AWSAccessKeyId>...</AWSAccessKeyId> </Error>
显然,如果从客户端提供内容类型字符串(在本例中为text / plain),则在字符串到符号中是预期的.不要问我为什么这会导致大(5.5MB?)文件超时.我希望这能为其他人节省几个小时的生命.
最简单的解决方法是删除该行
[request setValue:@"..." forHTTPHeaderField:@"Content-Type"];
如果您在创建预签名URL时知道内容类型,则可以将字符串添加到字符串到符号.
iOS – 同步上传到AWS S3
例如:https://github.com/awslabs/aws-sdk-ios-samples/blob/master/S3TransferManager-Sample/Swift/S3TransferManagerSampleSwift/UploadViewController.swift#L81
现在通常,这很好,但由于其他原因,我的工作已经在NSOperation子类中了,所以我想同步上传到S3以保持简单(否则,我需要实现异步NSOperation,并且更多样板……)
有人知道怎么做吗?
解决方法
let credentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.USEast1,identityPoolId: AwsCognitoIdentityPoolId) let configuration = AWSServiceConfiguration(region: AWSRegionType.USEast1,credentialsProvider: credentialsProvider) AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration let S3Client = AWSS3.defaultS3() let putObjectRequest = AWSS3PutObjectRequest() putObjectRequest.bucket = AwsBucketName putObjectRequest.key = key putObjectRequest.body = logFilePathURL do { let fileAttributes = try self.fileManager.attributesOfItemAtPath(logFilePathURL.path!) let fileSizeNumber = fileAttributes[NSFileSize] as! NSNumber putObjectRequest.contentLength = NSNumber(longLong: fileSizeNumber.longLongValue) } catch _ as NSError { // Todo handle error } S3Client.putObject(putObjectRequest).continueWithBlock { (task: AWSTask) -> AnyObject? in return nil }.waitUntilFinished()
…是啊.我无法在任何地方找到一个例子,所以我必须阅读源代码并解决问题.至于那个aws-sdk-ios库,谈论过度工程……需要一段时间才能通过所有这些间接层来弄明白.
无论如何,在我返回nil的最后一个区块中,你处理错误等等.
java-使用Retrofit2将文件上传到AWS S3预签名URL
我正在尝试使用预先签名的URL将文件上传到Amazon的S3.我从生成URL的服务器获取URL.将其作为JSON对象的一部分发送给我.我将URL作为字符串获取,如下所示:
https://com-example-mysite.s3-us-east-1.amazonaws.com/userFolder/ImageName?X-Amz-Security-Token=xxfooxx%2F%2F%2F%2F%2F%2F%2F%2F%2F%2Fxxbarxx%3D&X-Amz-Algorithm=xxAlgoxx&X-Amz-Date=20170831T090152Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=xxcredxx&X-Amz-Signature=xxsignxx
不幸的是,当我将其传递给Retrofit2时,它修改了String并试图将其制成URL.我已经设置了encoding = true,它可以解决大多数问题,但不能完全解决.我知道字符串按原样工作.我已经在Postman&得到成功的回应.
1st我尝试只是将String(除了我作为baseUrl剪切的东西)整体放入Path
public interface UpdateImageInterface {
@PUT("{url}")
Call<Void> updateImage(@Path(value="url", encoded=true) String url, Body RequestBody image);
}
调用代码:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://com-example-mysite.s3-us-east-1.amazonaws.com/userFolder/")
.build();
UpdateImageInterface imageInterface = retrofit.create(UpdateImageInterface.class);
// imageUrl is "ImageName..."
Call<Void> call = imageInterface.updateImage(imageUrl, requestFile);
除“?”外,此方法大部分有效(在“ ImageName”之后)转换为“?”.这会导致请求错误/ 400.
我的下一个尝试是使用Retrofit2创建查询,然后将整个String(带有多个查询)转储到查询中.
public interface UpdateImageInterface {
@PUT("ImageName")
Call<Void> updateProfilePhoto(@Query(value="X-Amz-Security-Token", encoded = true) String token, @Body RequestBody image);
}
调用代码:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://com-example-mysite.s3-us-east-1.amazonaws.com/userFolder/")
.build();
UpdateImageInterface imageInterface = retrofit.create(UpdateImageInterface.class);
// imageUrl is "xxfooxx..."
Call<Void> call = imageInterface.updateImage(imageUrl, requestFile);
这得到“?”正确呈现,但所有的’&’更改为“&”
最后,我尝试在baseUrl()中传递整个String,但是由于结尾没有’/’,因此给出了IllegalArgumentException.
我知道我可以解析预先签名的URL来进行多个查询,在应进行查询的情况下将它们组装在Retrofit2中,但我想避免这种处理.
要重申这个问题:
有没有一种方法可以使用Retrofit2轻松地(无需进行大量的字符串分析)将带有预签名URL的文件上传到S3?
解决方法:
在同事的帮助下,这就是解决方案.
public interface UpdateImageInterface {
@PUT
Call<Void> updateImage(@Url String url, @Body RequestBody image);
}
调用代码:
String CONTENT_IMAGE = "image/jpeg";
File file = new File(localPhotoPath); // create new file on device
RequestBody requestFile = RequestBody.create(MediaType.parse(CONTENT_IMAGE), file);
/* since the pre-signed URL from S3 contains a host, this dummy URL will
* be replaced completely by the pre-signed URL. (I'm using baseURl(String) here
* but see baseUrl(okhttp3.HttpUrl) in Javadoc for how base URLs are handled
*/
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.dummy.com/")
.build();
UpdateImageInterface imageInterface = retrofit.create(UpdateImageInterface.class);
// imageUrl is the String as received from AWS S3
Call<Void> call = imageInterface.updateImage(imageUrl, requestFile);
Javadoc获取@Url(类Url)&
baseUrl()(Retrofit.Builder类)
MediaType是OkHttp库中的一个类,经常与Retrofit(均来自Square)一起使用.可以在Javadoc中找到有关传递给parse方法的常量的信息.
javascript – 如何使用Meteor将文件上传到Amazon S3?
这是亚马逊的错误消息:
Conflicting query string parameters: acl,policy
策略和签名被编码,对于Node.js使用Crypto.js
var crypto=Npm.require("crypto");
我正在尝试使用Meteor HTTP.post方法构建POST请求.这也可能是错误的.
var BucketName="mybucket"; var AWSAccessKeyId="MY_ACCES_KEY"; var AWSSecretKey="MY_SECRET_KEY"; //create policy var POLICY_JSON={ "expiration": "2009-01-01T00:00:00Z","conditions": [ {"bucket": BucketName},["starts-with","$key","uploads/"],{"acl": 'public-read'},"$Content-Type",""],["content-length-range",1048576],] } var policyBase64=encodePolicy(POLICY_JSON); //create signature var SIGNATURE = encodeSignature(policyBase64,AWSSecretKey); console.log('signature: ',SIGNATURE);
这是我与Meteor一起使用的POST请求:
//Send data---------- var options={ "params":{ "key":file.name,'AWSAccessKeyId':AWSAccessKeyId,'acl':'public-read','policy':policyBase64,'signature':SIGNATURE,'Content-Type':file.type,'file':file,"enctype":"multipart/form-data",} } HTTP.call('POST','https://'+BucketName+'.s3.amazonaws.com/',options,function(error,result){ if(error){ console.log("and HTTP ERROR:",error); }else{ console.log("result:",result); } });
她正在编码政策和签名:
encodePolicy=function(jsonPolicy){ // stringify the policy,store it in a NodeJS Buffer object var buffer=new Buffer(JSON.stringify(jsonPolicy)); // convert it to base64 var policy=buffer.toString("base64"); // replace "/" and "+" so that it is URL-safe. return policy.replace(/\//g,"_").replace(/\+/g,"-"); } encodeSignature=function(policy,secret){ var hmac=crypto.createHmac("sha256",secret); hmac.update(policy); return hmac.digest("hex"); }
A不知道发生了什么. POST方法或加密可能已经有问题,因为我不太了解这些方法.如果有人可以指出我正确的方向,编码或发送POST请求到AmazonS3正确,它可以帮助很多.
(我不喜欢使用filepicker.io,因为我不想强制客户端在那里注册.)
提前致谢!!!
解决方法
meteor add edgee:slingshot
在服务器端声明您的指令:
Slingshot.createDirective("myFileUploads",Slingshot.S3Storage,{ bucket: "mybucket",allowedFileTypes: ["image/png","image/jpeg","image/gif"],acl: "public-read",authorize: function () { //You can add user restrictions here return true; },key: function (file) { return file.name; } });
该指令将自动生成策略和签名.
他们只是上传它:
var uploader = new Slingshot.Upload("myFileUploads"); uploader.send(document.getElementById('input').files[0],function (error,url) { Meteor.users.update(Meteor.userId(),{$push: {"profile.files": url}}); });
关于如何在Go中将预签名的POST上传到AWS S3?的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于ios – 使用预签名URL将文件上传到AWS S3的代码有什么问题?、iOS – 同步上传到AWS S3、java-使用Retrofit2将文件上传到AWS S3预签名URL、javascript – 如何使用Meteor将文件上传到Amazon S3?的相关信息,请在本站寻找。
本文标签: