2011-11-15 8 views
6

Javascript & NodeJSを使用して、署名済みのS3 URLを作成しようとしています。私はthis 仕様を使用しました。Javascriptで符号付きS3 URLを作成する

SignatureDoesNotMatch 

The request signature we calculated does not match the signature you provided. 
Check your key and signing method. 

署名を作成するときに私が間違っているのは何:

https://s3-eu-west-1.amazonaws.com/mybucket/test.txt?AWSAccessKeyId=XXXXXX&Expires=1331290899&Signature=EciGxdQ1uOqgFDCRon4vPqTiCLc%3D 

は、しかし、私はそれにアクセスして、次のエラーが表示されます。

var crypto  = require('crypto'), 
    date  = 1331290899, 
    resource = '/myfile.txt', 
    awskey  = "XXXX", 
    awssecret = "XXXX"; 

var stringToSign ='GET\n\n\n' + date + '\n\n' + resource; 

var sig = encodeURIComponent(crypto.createHmac('sha1', awssecret).update(stringToSign).digest('base64')); 

var url = "https://s3-eu-west-1.amazonaws.com/mybucket" + 
     resource + "?AWSAccessKeyId=" + awskey + "&Expires="+ date + 
     "&Signature="+ sig 

これは、このようなURLが作成されますか?

EDIT - KNOX WITH ATTEMPT

私は今署名したURLを生成するためにノックスを使用しようとしています。私はダウンロードを強制的に要求するヘッダーを追加する必要があります。私は、次のように編集しています

を追加amazonHeaders: 'response-content-disposition:attachment', client.signedUrl-するhttp://jsfiddle.net/BpGNM/1/

追加options.amazonHeaders + '\n' +auth.queryStringToSignへ - 今SIGを作成するためにauth.hmacSha1に送信されて

http://jsfiddle.net/6b8Tm/メッセージは次のとおりです。

'GET\n\n\n1321374212\nresponse-content-disposition:attachment\n/meshmesh-dev/test/Readme.md' 

これで、GET varとしてresponse-content-disposition=attachmentが追加された新しいURLにアクセスしようとしました。しかし、私はまだ上記の同じエラーを受けています。

+0

あなたと同じ問題がありましたら、これは解決されましたか? –

答えて

8

KnoxをNode.Jsとともに使用しようとします。その偉大な組み合わせであることが知られており、また、それ自体は、あなたが何をしようとしての一種であるNode.jsの暗号化ライブラリを利用して - あなたにここに:)

詳細情報時間を節約:あなたは、https://github.com/LearnBoost/knox

ザンをちょうどのような何かができる:

var knox = require('knox'); 
var s3Client = knox.createClient({ 
    key: 'XXX', 
    secret: 'XXX', 
    bucket: 'XXX' 
}); 

var expires = new Date(); 
expires.setMinutes(expires.getMinutes() + 30); 
var url = s3Client.signedUrl(filename, expires); 

編集: ます。また、ノックスに見て、ちょうどsignedUrl機能が何をチェックして、あなたは余分なオプションがamazonHeadersと呼ばauth.signQuery通話に追加できyourself.Thanことを実装することができます:

Client.prototype.signedUrl = function(filename, expiration){ 
    var epoch = Math.floor(expiration.getTime()/1000); 
    var signature = auth.signQuery({ 
    amazonHeaders: 'response-content-disposition:attachment', 
    secret: this.secret, 
    date: epoch, 
    resource: '/' + this.bucket + url.parse(filename).pathname 
    }); 

    return this.url(filename) + 
    '?Expires=' + epoch + 
    '&AWSAccessKeyId=' + this.key + 
    '&Signature=' + encodeURIComponent(signature); 
}; 

シャイ。

+0

ありがとうございます。私はKnoxを使用していましたが、リクエストでヘッダーを送信する必要がありました( 'response-content-disposition ':attachment') - 私は自分のURLに署名しようとしました。これがノックスでどのように行われたのか? – Kit

+1

あなたのために私の答えを編集 –

+1

ありがとうございました。今いくつか試してみてください... – Kit

3

多分1つの改行が多すぎますか?

var stringToSign ='GET\n\n\n' + date + '\n\n' + resource; 

ここでそのすべてのヘルプは間違いなく動作するゴミのPHPの実装である場合:

class myS3Helper{ 
public function getSignedImageLink($timeout = 1800) 
    { 

     $now = new Zend_Date(); //Gives us a time object that is set to NOW 
     $now->setTimezone('UTC'); //Set to UTC a-la AWS requirements 
     $now->addSecond($timeout); 
     $expirationTime = $now->getTimestamp(); //returns unix timestamp representation of the time. 

     $signature = urlencode(
       base64_encode(
         hash_hmac(
           'sha1', $this->_generateStringToSign($expirationTime), 
           $my_aws_secretkey, 
           true 
           ) 
         ) 
       ); 

     //FIXME make this less ugly when I know it works 
     $url = 'https://'; 
     $url .= Zend_Service_Amazon_S3::S3_ENDPOINT; //e.g s3.amazonaws.com 
     $url .= $this->_getImagePath(); //e.g /mybucket/myFirstCar.jpg 
     $url .='?AWSAccessKeyId=' . $my_aws_key; 
     $url .='&Signature=' . $signature; //signature as returned by below function 
     $url .='&Expires=' . $expirationTime; 

     return $url; 


    } 

    protected function _generateStringToSign($expires) 
    { 

     $string = "GET\n"; //Methods 
     $string .= "\n"; 
     $string .= "\n"; 
     $string .= "$expires\n"; //Expires 
     $string .= $this->_getImagePath(); 

     return $string; 
    } 

}

EDIT--

は、このノードを見てください。js s3のアップロードコード、(それは私のではないが、私のMac上で横たわっている - 誰かにそれを属性することができますので、私に知らせて、私は小道具を行うだろう)が見つかりました。うまくいけば、これは(第三幸運時間)AWS-SDKおよびRxを使用して

https://gist.github.com/1370593

+0

私は上記の機能が何をしているのか試してみます。しかし、有効期限の後に余分な '\ n'がなくても、sigは失敗します。 – Kit

+0

申し訳ありませんが、あなたのための適切な言語ではなく、少し鈍いですが、それは私が手にしていた最初のことです - あなたは私に知らせるために何か質問がある場合。 –

+0

最後の最後のショット...バケットは/etc/test.txtだけでなく、.e.g /mybucket/test.txtリソースにあるべきですか? –

0

私の実装を助けるかもしれません。

import AWS from "aws-sdk" 
import Rx from 'rx' 

/* 
* Credentials could be loaded from env variables 
* http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-environment.html 
* */ 

const s3 = new AWS.S3({apiVersion: '2006-03-01'}); 

export function getS3SignedImage(objectKey) { 
    return Rx.Observable.create(function (observer) { 
     s3.getSignedUrl('getObject',{ 
      Bucket: process.env.AWS_BUCKET, 
      Key: objectKey 
     }, (err, data) => { 
      if (err) { 
       return observer.onError(err); 
      } 
      observer.onNext(data); 
      observer.onCompleted(); 
     }); 
    }); 
} 
関連する問題