supabase-storage について
Storage APIを通じてSupabaseのファイルストレージを管理するスキルです。バケットやファイルの操作、URL生成、アクセス制御の手順を扱います。
主な機能
- 01バケットの作成、一覧表示、管理
- 02ファイルのアップロード、ダウンロード、移動、コピー
- 03フォルダーまたは検索語によるファイル一覧
- 04公開URLと一時的な署名付きURLの生成
- 05Storage PoliciesとRLSによるアクセス制御のガイド
活用シーン
- 01アプリ用のバケットの作成と設定
- 02ユーザーのアバターのアップロードや保存ファイルの取得
- 03ファイルの検索とオブジェクトの一括整理
- 04非公開ドキュメントの期限付きリンク生成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ nice-wolf-studio/ claude-code-supabase-skills --skill supabase-storageインストール後、Claude Code で/supabase-storageを入力して読み込まれたか確認します。
詳細
Supabase Storage の操作
概要
このスキルでは、Supabase Storage API を通じてファイルストレージを操作できます。バケットの管理、ファイルのアップロード/ダウンロード、ファイルの一覧表示、URL の生成、アクセス制御の管理に対応しています。
前提条件
必須の環境変数:
export SUPABASE_URL="https://your-project.supabase.co"
export SUPABASE_KEY="your-anon-or-service-role-key"
ヘルパースクリプト: このスキルでは、共有の Supabase API ヘルパーを使用します。必ず読み込んでください:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
バケットの操作
バケットの一覧表示
すべてのストレージバケットを取得します:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
supabase_get "/storage/v1/bucket"
バケットの作成
新しいストレージバケットを作成します:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
# Public bucket
supabase_post "/storage/v1/bucket" '{
"name": "avatars",
"public": true
}'
# Private bucket
supabase_post "/storage/v1/bucket" '{
"name": "private-documents",
"public": false,
"file_size_limit": 52428800,
"allowed_mime_types": ["image/png", "image/jpeg", "application/pdf"]
}'
バケットの詳細取得
バケット情報を取得します:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
supabase_get "/storage/v1/bucket/avatars"
バケットの更新
バケットの設定を更新します:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
curl -s -X PUT \
"${SUPABASE_URL}/storage/v1/bucket/avatars" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-H "Content-Type: application/json" \
-d '{
"public": false,
"file_size_limit": 10485760
}'
バケットの削除
バケットを削除します(空にする必要があります):
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
supabase_delete "/storage/v1/bucket/old-bucket"
バケットを空にする
バケット内のすべてのファイルを削除します:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
supabase_post "/storage/v1/bucket/avatars/empty" '{}'
ファイルの操作
ファイルのアップロード
ファイルをストレージにアップロードします:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
FILE_PATH="/path/to/local/image.jpg"
STORAGE_PATH="user-123/profile.jpg"
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-F "file=@${FILE_PATH}"
アップサートでアップロードします(存在する場合は上書き):
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-H "x-upsert: true" \
-F "file=@${FILE_PATH}"
コンテンツタイプを指定してアップロードします:
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-H "Content-Type: image/jpeg" \
-F "file=@${FILE_PATH}"
ファイルのダウンロード
ストレージからファイルをダウンロードします:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/profile.jpg"
OUTPUT_FILE="/path/to/save/downloaded.jpg"
curl -s -X GET \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-o "${OUTPUT_FILE}"
標準出力にダウンロードします(他のコマンドにパイプします):
curl -s -X GET \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}"
ファイルの一覧表示
バケット内のファイルを一覧表示します:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
supabase_post "/storage/v1/object/list/${BUCKET_NAME}" '{
"limit": 100,
"offset": 0,
"sortBy": {
"column": "name",
"order": "asc"
}
}'
特定のフォルダー内のファイルを一覧表示します:
supabase_post "/storage/v1/object/list/${BUCKET_NAME}" '{
"prefix": "user-123/",
"limit": 100
}'
ファイルを検索します:
supabase_post "/storage/v1/object/list/${BUCKET_NAME}" '{
"search": "profile",
"limit": 50
}'
ファイルの削除
単一のファイルを削除します:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/old-profile.jpg"
supabase_delete "/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}"
複数のファイルを削除します:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
supabase_delete "/storage/v1/object/${BUCKET_NAME}" -d '{
"prefixes": ["user-123/temp/", "user-456/draft/"]
}'
ファイルの移動/名前変更
ファイルを移動または名前変更します:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
FROM_PATH="user-123/temp.jpg"
TO_PATH="user-123/final.jpg"
supabase_post "/storage/v1/object/move" '{
"bucketId": "'"${BUCKET_NAME}"'",
"sourceKey": "'"${FROM_PATH}"'",
"destinationKey": "'"${TO_PATH}"'"
}'
ファイルのコピー
ファイルを別の場所にコピーします:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
SOURCE_PATH="user-123/profile.jpg"
DEST_PATH="user-123/profile-backup.jpg"
supabase_post "/storage/v1/object/copy" '{
"bucketId": "'"${BUCKET_NAME}"'",
"sourceKey": "'"${SOURCE_PATH}"'",
"destinationKey": "'"${DEST_PATH}"'"
}'
URL の生成
公開 URL の取得
ファイルの公開 URL を取得します(公開バケットのみ):
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/profile.jpg"
PUBLIC_URL="${SUPABASE_URL}/storage/v1/object/public/${BUCKET_NAME}/${STORAGE_PATH}"
echo "Public URL: $PUBLIC_URL"
署名付き URL の作成
一時的なアクセス用の署名付き URL を生成します:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="private-documents"
STORAGE_PATH="user-123/secret.pdf"
EXPIRES_IN=3600 # 1 hour in seconds
supabase_post "/storage/v1/object/sign/${BUCKET_NAME}/${STORAGE_PATH}" '{
"expiresIn": '"${EXPIRES_IN}"'
}'
レスポンスには次の内容が含まれます:
{
"signedURL": "/storage/v1/object/sign/private-documents/user-123/secret.pdf?token=..."
}
完全な URL:
signed_path=$(supabase_post "/storage/v1/object/sign/${BUCKET_NAME}/${STORAGE_PATH}" '{"expiresIn": 3600}' | jq -r '.signedURL')
full_url="${SUPABASE_URL}${signed_path}"
echo "Signed URL: $full_url"
複数の署名付き URL の作成
複数のファイルの署名付き URL を生成します:
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="private-documents"
supabase_post "/storage/v1/object/sign/${BUCKET_NAME}" '{
"paths": ["doc1.pdf", "doc2.pdf", "folder/doc3.pdf"],
"expiresIn": 3600
}'
よくあるパターン
進捗状況を表示しながらアップロード
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="uploads"
FILE_PATH="/path/to/large-file.zip"
STORAGE_PATH="user-123/backup.zip"
echo "Uploading ${FILE_PATH}..."
curl -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-F "file=@${FILE_PATH}" \
--progress-bar -o /dev/null
if [[ $? -eq 0 ]]; then
echo "Upload successful!"
else
echo "Upload failed!"
exit 1
fi
ファイルの存在確認
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/profile.jpg"
# Try to get file info
response=$(curl -s -X GET \
"${SUPABASE_URL}/storage/v1/object/info/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-w "\n%{http_code}")
http_code=$(echo "$response" | tail -n1)
if [[ $http_code -eq 200 ]]; then
echo "File exists"
else
echo "File does not exist"
fi
複数のファイルを一括アップロード
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="uploads"
LOCAL_DIR="/path/to/files"
for file in "$LOCAL_DIR"/*; do
filename=$(basename "$file")
echo "Uploading $filename..."
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/batch/${filename}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-F "file=@${file}"
echo "✓ Uploaded $filename"
done
バケット内のすべてのファイルをダウンロード
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
OUTPUT_DIR="/path/to/download"
mkdir -p "$OUTPUT_DIR"
# Get file list
files=$(supabase_post "/storage/v1/object/list/${BUCKET_NAME}" '{"limit": 1000}')
# Download each file
echo "$files" | jq -r '.[].name' | while read -r filename; do
echo "Downloading $filename..."
curl -s -X GET \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${filename}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-o "${OUTPUT_DIR}/${filename}"
echo "✓ Downloaded $filename"
done
画像変換
画像をその場で変換します(公開バケット):
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/profile.jpg"
# Resize to width 200px
TRANSFORMED_URL="${SUPABASE_URL}/storage/v1/render/image/public/${BUCKET_NAME}/${STORAGE_PATH}?width=200"
# Resize with quality
TRANSFORMED_URL="${SUPABASE_URL}/storage/v1/render/image/public/${BUCKET_NAME}/${STORAGE_PATH}?width=200&quality=80"
# Multiple transformations
TRANSFORMED_URL="${SUPABASE_URL}/storage/v1/render/image/public/${BUCKET_NAME}/${STORAGE_PATH}?width=300&height=300&resize=contain"
アクセス制御
ストレージへのアクセスは、Supabase ダッシュボードの Storage Policies(RLS)によって制御されます。
よくあるポリシーの例:
公開読み取り、認証済みユーザーによる書き込み:
-- Set in Supabase Dashboard > Storage > Policies
-- Allow public to read
SELECT: true for all users
-- Allow authenticated users to upload their own files
INSERT: auth.uid() = (storage.foldername(name))[1]
ユーザーごとのフォルダー:
-- Users can only access files in their own folder
SELECT: auth.uid() = (storage.foldername(name))[1]
UPDATE: auth.uid() = (storage.foldername(name))[1]
DELETE: auth.uid() = (storage.foldername(name))[1]
エラー処理
よくあるエラー:
| ステータス | エラー | 意味 |
|---|---|---|
| 400 | Invalid bucket name | バケット名に無効な文字が含まれています |
| 404 | Object not found | ファイルが存在しません |
| 409 | Bucket already exists | その名前のバケットはすでに存在します |
| 413 | Payload too large | ファイルがサイズ上限を超えています |
| 422 | Invalid MIME type | このバケットで許可されていないファイル形式です |
セキュリティのベストプラクティス
- 機密データにはプライベートバケットを使用します
- アクセス制御のためにStorage Policies(RLS)を実装します
- 不正利用を防ぐためにファイルサイズの上限を設定します
- 想定されるファイル形式にMIME タイプを制限します
- プライベートファイルへの一時的なアクセスには署名付き URL を使用します
- ファイルをユーザーごとのフォルダー(例:
user-{uuid}/)に整理します - クライアントアプリケーションにサービスロールキーを決して公開しないでください
ファイルサイズの上限
- デフォルトの最大ファイルサイズ:50MB
- バケットごとに最大 5GB まで設定できます(それ以上の場合は Supabase にお問い合わせください)
- 現在の上限はバケットの設定で確認してください
API ドキュメント
Supabase Storage API の全ドキュメント:https://supabase.com/docs/guides/storage