素のPHPでさくらのオブジェクトストレージをlistobject
前回AWS-SDKを使ったが、素のPHPだとどうなるか試した。
やったこと
Fiddlerでリクエストを確認
FiddlerでCloudBerryのリクエストをとった。
GET /<<バケット>>?prefix=&max-keys=1000&delimiter=%2F HTTP/1.1 User-Agent: CloudBerryLab.Base.HttpUtil.Client 4.3.0 ( http://www.cloudberrylab.com/) x-amz-date: Fri, 20 Nov 2015 12:21:06 GMT Authorization: AWS <<アクセスキー>>:xxxxxxxxxxxxxxxxxxxxxxxxxxx= Host: b.sakurastorage.jp Connection: Keep-Alive
アクセスキーの右ブロックは
- 同じリクエストでも毎回変わることから時間が関係してるっぽい
- 最後が「=(イコール)」で終わるのでBASE64っぽい
ってことが分かった。
AWS 署名V2を調べた
アクセスキーの右ブロックの文字列は「AWS 署名バージョン 2」と呼ぶようだ。 さくらのオブジェクトストレージは、AWSSDKv2は成功するがv3は失敗するので、 v2をつかうといいようだ。
V2署名文字列生成は↓が分かり易かったです。
付録 B: リクエストの認証(AWS 署名バージョン 2) https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/auth-request-sig-v2.html
PHP で Amazon S3 の REST API を使用 #1 http://www.applelife100.com/2012/06/23/using-rest-api-of-amazon-s3-in-php-1/
素のPHPでListObject
こんな感じになりました。
<?php $config = [ 'bucket' => '<<バケット>>', 'accessKey' => '<<アクセスキー>>', 'secretAccessKey' => '<<シークレットアクセスキー>>', 'endpoint' => 'b.sakurastorage.jp', ]; $resource = "/{$config['bucket']}"; $req = makeRequest($config, $resource); $res = file_get_contents($req['url'], false, $req['context']); echo $res; function makeRequest($config, $resource) { $datetime = new DateTime('now', new DateTimeZone('UTC')); $date = $datetime->format(DateTime::RFC1123); $signature = v2signature($config, "GET", '', '', $datetime, '', $resource); return [ 'context' => stream_context_create([ "http" => [ 'method' => 'GET', 'header' => implode("\r\n", [ "Authorization: AWS {$config['accessKey']}:{$signature}", "Date: {$date}", ]), ], ]), 'url' => "https://{$config['endpoint']}{$resource}", ]; } function v2signature($config, $httpVerb, $contentMd5, $contentType, $datetime, $canonicalizedAmzHeaders, $resource) { $stringToSign = $httpVerb ."\n" . $contentMd5 ."\n" . $contentType ."\n" . $datetime->format(DateTime::RFC1123) ."\n" . $canonicalizedAmzHeaders . $resource; return base64_encode(hash_hmac('sha1', $stringToSign, $config['secretAccessKey'], true)); }