9
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Organization

Azure Storage に REST API でアップロードする

下記とにらめっこして Azure Storage に PHP の curl で REST API でファイルをアップロードしてみました。

あらかじめ下記の3つは作成しておいてください。

  • ストレージアカウント
  • ストレージコンテナ
  • ストレージのアクセスキー

アクセスキーは管理ポータルでストレージアカウントを選択した後の画面で、下のほうに項目が現れます。

01-access-key.png

プライマリとセカンダリで2つありますが使うのはどっちでもいいです。恐らくアクセスキーのローテートのために2つ設けられているのでしょう。

02-access-key.png

以下のようなコードで REST API でアップロードできます。

  • Date のタイムゾーンは +0000 だとダメ
    • \DateTime::RFC2822 とか "r" とかだとダメ
  • x-ms-* のヘッダーはコロンの後にスペースがあるとダメ
  • ストレージアクセスキーは Base64 エンコードされている
    • 署名で使うときにはデコードが必要
  • HMAC は SHA256 です
  • CanonicalizedResource にはストレージアカウント名も含みます
    • URL のパスとは一致しない
<?php
// ストレージアカウント
$account = 'YOUR_STORAGE_ACCOUNT';

// ストレージコンテナ
$container = 'YOUR_STORAGE_CONTAINER';

// ストレージのアクセスキー
$accessKey = 'YOUR_STORAGE_ACCESS_KEY';

$filename = 'sample.txt';
$body = 'php with curl';
$type = 'text/plain';

$headers = [
    'x-ms-blob-type:BlockBlob',
    'x-ms-version:2014-02-14',
];

$date = gmdate('D, d M Y H:i:s T');
$size = strlen($body);

$stringToSign = [
    // VERB
    'PUT',
    // Content-Encoding
    '',
    // Content-Language
    '',
    // Content-Length
    $size,
    // Content-MD5
    '',
    // Content-Type
    $type,
    // Date
    $date,
    // If-Modified-Since
    '',
    // If-Match
    '',
    // If-None-Match
    '',
    // If-Unmodified-Since
    '',
    // Range
    '',
];

$stringToSign = array_merge($stringToSign, $headers, ["/$account/$container/$filename"]);
$stringToSign = implode("\n", $stringToSign);

$signature = base64_encode(hash_hmac('sha256', $stringToSign, base64_decode($accessKey), true));
$authorization = "SharedKey $account:$signature";

$headers = array_merge($headers, [
    "Authorization:$authorization",
    "Date:$date",
    "Content-Type:$type",
    "Content-Length:$size",
]);

$ch = curl_init();

curl_setopt_array($ch, [
    CURLOPT_URL => "https://$account.blob.core.windows.net/$container/$filename",
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_HEADER => true,
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_POSTFIELDS => $body,
]);

curl_exec($ch);
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
9
Help us understand the problem. What are the problem?