2016-06-08 5 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> в настройках Корс ведра

Тогда мой угловой сервис с помощью 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 в IMG зашифрованную Base64, что-то вроде "/ 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, "retryable" ложь "retryDelay": +60,59883770067245}

Столько удовольствия ...

Update заголовки:

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 

Update

Даже при попытке загрузить содержимое без Base64 заканчивается с той же ошибкой

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

Update # 2

я переехал в раствор с подписанной 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

Freak Я, наконец, найти решение или, по крайней мере, решение.

После миграции моего клиентского решения aws-sdk на решение, где сервер сгенерировал подписанный url, я все еще сталкивался с той же ошибкой. Короткий рассказ, он устранил проблему, установив в обеих сторонах Content-type для заголовка.

Мой код, если кто-то столкнется с той же проблемой один день:

сервера Узел.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

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

    // Post image to S3 
    this.$http({ 
    method: 'PUT', 
    url: preSignedUrl, 
    headers: {'Content-Type': 'image/jpeg'}, 
    data: imgData 
    }) 
    .then((response:any) => { 
     console.log("Image uploaded to S3" + JSON.stringify(response)); 

     deferred.resolve(); 

    }, (response:any) => { 
     console.log("Error Presigned URL" + JSON.stringify(response)); 
     deferred.reject(response); 
    }); 

    return deferred.promise; 
} 
Смежные вопросы