2016-06-08 175 views
0

這讓我瘋狂,任何幫助將不勝感激!S3 putObject失敗使用aws-sdk

建立我的水桶在S3我跟着http://www.cheynewallace.com/uploading-to-s3-with-angularjs/

關於這個職位,我提出以下「改進」通過這種政策擴大使用通配符,並給予更多的權利

{ 
"Version": "2012-10-17", 
"Statement": [ 
    { 
     "Effect": "Allow", 
     "Action": [ 
      "s3:DeleteObject", 
      "s3:DeleteObjectVersion", 
      "s3:GetObject", 
      "s3:GetObjectAcl", 
      "s3:GetObjectTorrent", 
      "s3:GetObjectVersion", 
      "s3:GetObjectVersionAcl", 
      "s3:GetObjectVersionTorrent", 
      "s3:PutObject", 
      "s3:PutObjectAcl", 
      "s3:PutObjectVersionAcl" 
     ], 
     "Resource": [ 
      "arn:aws:s3:::photos-eu/*" 
     ] 
    } 
] 
} 

,並添加< ExposeHeader> ETag的</ExposeHeader>剷鬥

隨後的CORS廣告設置使用AWS-SDK我的角度服務看起來像

/// <reference path="../../../typings/tsd.d.ts" /> 

module Services { 

    export interface IS3UploadService { 
    upload(imgName:string, imgData:string):ng.IPromise<{}>; 
    } 

    export class S3UploadService implements IS3UploadService { 

static $inject = ['$q']; 

private bucket:AWS.S3; 

constructor(private $q:ng.IQService) { 
    var credentials = new AWS.Credentials("myAccessKeyId", "mySecretAccessKey"); 
    AWS.config.update(credentials); 
    AWS.config.region = "eu-west-1"; 

    this.bucket = new AWS.S3({params: {Bucket: 'peterparker-photos-eu', maxRetries: 10, region: "eu-west-1"}}); 

} 

upload(imgName:string, imgData:string):ng.IPromise<{}> { 
    var deferred = this.$q.defer(); 

    var params:AWS.s3.PutObjectRequest = { 
    Bucket: "peterparker-photos-eu", 
    Key: imgName, 
    Body: imgData, 
    ContentType: "image/jpeg", 
    ContentEncoding: "Base64" 
    }; 

    this.bucket.putObject(params, (err:any, data:any) => { 
    if (err) { 
     console.error("->" + JSON.stringify(err)); 
     deferred.reject(err); 
    } else { 
     console.info(data); 
     deferred.resolve(data); 
    } 
    }); 

    return deferred.promise; 
} 

    } 
} 

angular.module('App') 
    .service('S3UploadService', Services.S3UploadService); 

對於我的測試目的,我推入imgData編碼爲Base64一個img,像「/ 9J/4AAQSkZJRgABAgAAZABkA ......」(當然有效的圖像轉換與http://base64-image.de

而作爲結果,每次我嘗試,我有以下錯誤

{「line」:25,「column」:24996,「sourceURL」:「http://localhost:8100/lib/aws-sdk/dist/aws-sdk.min.js」,「message」:「我們計算的請求籤名不匹配您提供的簽名。檢查您的密鑰和簽名方法。「,」code「:」SignatureDoesNotMatch「,」region「:null,」time「:」2016-06-08T15:12:09.945Z「,」requestId「:null,」statusCode「: 403, 「重試」:假的, 「retryDelay」:60.59883770067245}

這麼多的樂趣......

更新標題:

General 
Request URL:https://peterparker-photos-eu.s3-eu-west-1.amazonaws.com/1465408512724.jpg 
Request Method:PUT 
Status Code:403 Forbidden 
Remote Address:54.231.131.16:443 

Response headers 
Access-Control-Allow-Methods:HEAD, GET, PUT, POST, DELETE 
Access-Control-Allow-Origin:* 
Access-Control-Expose-Headers:ETag, x-amz-meta-custom-header 
Connection:close 
Content-Type:application/xml 
Date:Wed, 08 Jun 2016 17:55:20 GMT 
Server:AmazonS3 
Transfer-Encoding:chunked 
Vary:Origin, Access-Control-Request-Headers, Access-Control-Request-  Method 
x-amz-id-... 
x-amz-request-id:... 

Request Headers 
Accept:*/* 
Accept-Encoding:gzip, deflate, sdch, br 
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,de;q=0.2 
Authorization:AWS ... 
Connection:keep-alive 
Content-Encoding:Base64 
Content-Length:38780 
Content-MD5:... 
Content-Type:image/jpeg; charset=UTF-8 
Host:peterparker-photos-eu.s3-eu-west-1.amazonaws.com 
Origin:http://localhost:8100 
Referer:http://localhost:8100/?ionicplatform=ios 
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5)    AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 
X-Amz-Date:Wed, 08 Jun 2016 17:55:20 GMT 
X-Amz-User-Agent:aws-sdk-js/2.3.18 

Request payload 
Img base64 code 

更新

即使是試圖上傳一個非Base64內容,它完成相同的錯誤

var paramsHtml:AWS.s3.PutObjectRequest = { 
    Bucket: "peterparker-photos-eu", 
    Key: "HelloWorld.html", 
    Body: "The Body", 
    ContentType: "text/html" 
    }; 

更新#2

我搬到同在下述溶液中描述我的節點JS服務器生成的標識的URL的解決方案,仍然得到了相同的錯誤結果......但我至少我嘗試;)

upload file from angularjs directly to amazon s3 using signed url

+0

你能粘貼你的測試圖像的完整imgData嗎? – error2007s

+0

當然,這裏你去:https://dl.dropboxusercontent.com/u/77620770/img.ts –

+0

該鏈接並不適合我 – error2007s

回答

0

怪胎,我終於找到了解決方案,或者至少一個解決方案。

將我的客戶端基於aws-sdk的解決方案遷移到服務器生成signedUrl的解決方案後,我仍面臨同樣的錯誤。短小的故事,它通過在標題的內容類型的兩側設置來解決問題。

我的代碼,如果有人面臨同樣的問題第一天:

服務器節點。JS

var AWS = require('aws-sdk'); 

AWS.config.update({accessKeyId: "myKey", secretAccessKey: "mySecret"}); 
AWS.config.region = 'eu-west-1'; 

app.post('/api/images', securityPolicy.authorise, function (req, res) { 

var s3 = new AWS.S3(); 

var imgName = req.body.imgName; 
var contentType = req.body.contentType; 

// Expires in seconds 
var params = {Bucket: 'photos-eu', Key: imgName, Expires: 600, ContentType: contentType}; 
s3.getSignedUrl('putObject', params, function (err, url) { 
    if (err) { 
     res.status(500).json({ 
      error: "Presigned S3 url for putObject can't be created. " + JSON.stringify(err) 
     }); 
    } else { 
     res.json({url: url}); 
    } 
}); 
}); 

客戶端角:

  • 首先或當然有到節點服務器,明顯POST調用到我的服務器

然後第二部分處理signedURL

部分 ​​