PHPでAzure Storageの画像を署名付きURLを使って見れるようにする(SAS)

3 min read読了の目安(約3200字

備忘のため書きます。
めっちゃめんどいので細かいとこは省略。

目的

つまりこれです。

Shared Access Signature (SAS) は、Azure Storage BLOB に対する制限付きのアクセス権を許可する URI です。お客様のストレージ アカウント キーを共有せずに特定の時間範囲のストレージ アカウント リソースへのアクセスを許可する場合に使用します。

環境

  • PHP 7.4.16
  • composer 2.0.11
  • azure-storage-php
  • Azure ストレージアカウント
    • サブスクリプション
      • 無料使用版
    • パフォーマンス/アクセス層
      • Standard/ホット
    • アカウントの種類
      • StorageV2 (汎用 v2)

前提

ストレージアカウントのコンテナに以下画像ファイルをアップロード済み。

※いらすとやから画像を拝借

https://www.irasutoya.com/2020/06/blog-post_169.html

コード書く

ディレクトリ構成

.
├── composer.json
├── composer.lock
├── index.php
└── vendor

コード

<?php

require_once "vendor/autoload.php";

use MicrosoftAzure\Storage\Blob\BlobRestProxy;
use MicrosoftAzure\Storage\Common\ServiceException;
use MicrosoftAzure\Storage\Blob\BlobSharedAccessSignatureHelper;
use MicrosoftAzure\Storage\Common\Internal\Resources;

function getBlobUrlWithSignature(string $filePath)
{
    try {
        // Default から始まってるやつ
        $connectionString = {接続文字列};
        $container = 'test-container';

        $blobClient = BlobRestProxy::createBlobService($connectionString);
        $url = $blobClient->getBlobUrl($container, $filePath);

        // cs から始まってるやつ
        $accountName = {ストレージ アカウント名};
	// keyです。「アクセス キー」から確認できます
        $accountKey = {キー};

        $helper = new BlobSharedAccessSignatureHelper($accountName, $accountKey);
        $d = new \Datetime('now', new \DateTimeZone('UTC'));

        // リソース
        // 以下どちらかを選択するとのこと
        // ・Resources::RESOURCE_TYPE_BLOB
        // ・Resources::RESOURCE_TYPE_CONTAINER
        $signedResource = Resources::RESOURCE_TYPE_BLOB;
        
        // リソース名
        // コンテナからのリソースの場所を指定
        $resourceName = "{$container}/{$filePath}";
        
        // パーミッション
        // リソースごとに指定できるパーミッション
        //  ・Resources::RESOURCE_TYPE_BLOB => ['r', 'a', 'c', 'w', 'd'],
        //  ・Resources::RESOURCE_TYPE_CONTAINER => ['r', 'a', 'c', 'w', 'd', 'l']
        $signedPermissions = 'r';

        // 開始日時
        // Datetime or string でOK
        $signedStart = new \Datetime();

        // 有効期限
        // 今回は1時間後
        $signedExpiry = date_modify(date_create(), '+1 hour');

        // IPを制限したい場合は指定
        $signedIP = "";

        // 有効なプロトコル
        // https or httpだと思う
        $signedProtocol = "https";

        // ほかにも引数で指定できるが今回は不要なので省略

        $token = $helper->generateBlobServiceSharedAccessSignatureToken(
            $signedResource,
            $resourceName,
            $signedPermissions,
            $signedExpiry,
            $signedStart,
            $signedIP,
            $signedProtocol
        );

        return "{$url}?{$token}";
    } catch (ServiceException $e) {
        $code = $e->getCode();
        $errorMessage = $e->getMessage();
        echo "{$code}: {$errorMessage}" . PHP_EOL;
    }
}

echo getBlobUrlWithSignature('pose_pien_uruuru_woman.png') . PHP_EOL;

実行してみる

$ php index.php
https://{ストレージ アカウント名}.blob.core.windows.net/test-container/pose_pien_uruuru_woman.png?sv=2017-11-09&sr=b&st=2021-04-16T01:49:29Z&se=2021-04-16T02:49:29Z&sp=r&spr=https&sig=%2FPm0%2BgX4Iq8yvtLsgrTmis6VGJXEe5Gor9601cI6%2Fx4%3D

以上!