亚马逊 s3 与 AFAmazonS3Manager + AFNetworking

Posted

技术标签:

【中文标题】亚马逊 s3 与 AFAmazonS3Manager + AFNetworking【英文标题】:amazon s3 with AFAmazonS3Manager + AFNetworking 【发布时间】:2014-03-05 21:22:01 【问题描述】:

我正在尝试使用 AFAmazonS3Manager 将一些文件上传到 amazon s3,但出现 403 禁止错误,我尝试列出存储桶中的所有对象,同样的错误。

存储桶对所有人都是读/写的。

代码:

AFAmazonS3Manager *s3Mamanager=[[AFAmazonS3Manager alloc]initWithAccessKeyID:@"XXXXXX" secret:@"xxxxxx"];

[s3Mamanager getBucket:@"aBucket" success:^(id responseObject) 

 failure:^(NSError *error) 

];

错误:

 Error Domain=AFNetworkingErrorDomain Code=-1011 "Request failed:
 forbidden (403)" UserInfo=0x170272580
 AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse:
 0x1782212e0>  URL: https://s3.amazonaws.com/aBucket   status code:
 403, headers 
     "Content-Type" = "application/xml";
     Date = "Wed, 05 Mar 2014 21:01:55 GMT";
     Server = AmazonS3;
     "Transfer-Encoding" = Identity;
     "x-amz-id-2" = "xxxxxxxxxxxxxx";
     "x-amz-request-id" = xxxxxxxxxxxxxx;  , NSLocalizedDescription=Request failed: forbidden (403),
 NSErrorFailingURLKey=https://s3.amazonaws.com/aBucket

我使用传输 (mac) 和 Amazon s3 ios API 的示例,它工作正常,我想使用 NSURLSession 上传文件(使用 AFNetworking)。

PS:在 AFAmazonS3Manager 中,一些比赛块有“long long”作为参数,但 AFNetwoking 使用 NSIteger,所以我修改了它们,我认为这不是问题,但我真的很喜欢这个所以..

【问题讨论】:

【参考方案1】:

失败的原因是在 AFAmazonS3RequestSerializer 中计算签名的方式存在错误。它正在尝试使用以下方法创建签名:

NSString *canonicalizedResource = [NSString stringWithFormat:@"/%@%@", self.bucket, request.URL.path];

此时,self.bucket 为空并且 request.URL.path 包含存储桶。您可以通过以下方式解决该问题:

AFAmazonS3Manager *s3Manager = [[AFAmazonS3Manager alloc]
                                initWithAccessKeyID:@"<accessKeyID>" secret:@"<secret>"];
[[s3Manager requestSerializer] setBucket:@"<YOUR BUCKET HERE>"];
[s3Manager getBucket:@"/" success:^(id responseObject) 
             failure:^(NSError *error) ];

或者这个:

AFAmazonS3Manager *s3Manager = [[AFAmazonS3Manager alloc]
                                initWithAccessKeyID:@"<accessKeyID>" secret:@"<secret>"];
[[s3Manager requestSerializer] setBucket:@"<YOUR BUCKET HERE>"];
[s3Manager enqueueS3RequestOperationWithMethod:@"GET" path:@"/" parameters:nil
                                       success:^(id responseObject) 
                                       failure:^(NSError *error) ];

【讨论】:

【参考方案2】:

我在使用 putObjectWithFile 方法时遇到了同样的问题。

我没有设置存储桶,而是在 AFAmazonS3Manager 似乎打算支持的 destinationPath 上传递存储桶名称。存储桶属性已设置或通过路径传递。

我在这里提交了一个拉取请求,其中包含对我有用的修复https://github.com/AFNetworking/AFAmazonS3Client/pull/38

您必须将 long long 更改为 NSInteger 也是正确的。

【讨论】:

以上是关于亚马逊 s3 与 AFAmazonS3Manager + AFNetworking的主要内容,如果未能解决你的问题,请参考以下文章

AWS上EC2与S3通过私有链接通信(同区)

AWS Lambda 函数写入 S3

在 react-native 中将图像上传到亚马逊 s3

不使用亚马逊 S3 存储桶创建亚马逊云端分发

亚马逊 s3 / 其他 AWS 服务上的操作日志

亚马逊s3上的zcat