LoginSignup
4
2

More than 5 years have passed since last update.

Node.jsのAWS-SDKでPreSignedURLでPUTするとはまった件

Posted at

眠いので手短にまとめる。

普通にPUTするURL取得する

import AWS from "aws-sdk";

const s3 = new AWS.S3();
async function getPresignedURLForPUT(path){
   return new Promise((resolve,reject)=>{
        s3.getSignedUrl("putObject", {
                Bucket: "example.com",
                Key: path,
                Expires: 60 * 60 * 24 * 365
        }, (err, url) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(url);
                }
        });
   });
}

console.log(await getPresignedURLForPUT("aaa/bbb.jpg");

AWSのアクセスキーやシークレットなどは環境変数に入っている前提。 AWS_DEFAULT_REGIONも環境変数に入っている。

最初の洗礼

この状態でやったら、URLは取得できるものの、送ろうとすると301エラーが出る。

<Error>
<script/>
<Code>PermanentRedirect</Code>
<Message>
The bucket you are attempting to access must be addressed using the 
specified endpoint. Please send all future requests to this endpoint.
</Message>
<Bucket>XXX.COM</Bucket>
<Endpoint>XXX.COM.s3.amazonaws.com</Endpoint>
<RequestId>A82721F2A44XXXX</RequestId><HostId>HPgWeSUk2cKu3AbijEu9+S41bHh7dUxSiwOEEVrS08dsrpJ3AvMP5V2iXXXXXX
</HostId>
</Error>

こんな感じのエラーが出る。検索するとリージョン関連のエラーである様だが、環境変数には入っている。

ダメ元で以下の様にしてもダメ。

const s3 = new AWS.S3();
s3.config.update({region:"ap-northeast-1"});

ところが以下の様にすると問題ないようになった。

AWS.config.update({region:"ap-northeast-1"});
const s3 = new AWS.S3();

弐の壁

先ほどので別のURLが帰って来る様になり、PUTリクエストが送れる様であったが、SignatureDoesNotMatchエラーが出る。

これによると、以下が必要になるらしい。

var s3 = new AWS.S3({
  signatureVersion: 'v4'
});

最後の壁

v4だと一週間以上の有効期限のSignatureは作れないらしい。諦めて1週間有効なSignatureを作った。

所感

そもそも設定おかしいなら最初からSigned-URL返して来るなよ。っていう感じではある。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2