Azurite利用時におけるCORSエラーの解決策

はじめに

ローカル環境でAzure StorageをエミュレートするAzuriteは非常に有用なツールです。しかし、その利用過程でCORS (Cross-Origin Resource Sharing) に起因する問題が発生することがあります。本記事では、その具体的な解決策について解説します。

発生した問題

開発中のWebアプリケーションから、Dockerコンテナで稼働しているAzurite上のBlobストレージにアクセスを試みた際、以下のCORSエラーが発生しました。

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at ‘http://127.0.0.1:10000/devstoreaccount1/test-container/xxx’. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

このエラーは、WebアプリケーションのオリジンとAzuriteのオリジンが異なるために、ブラウザの同一オリジンポリシーによってリクエストがブロックされることによって生じます。

前提

docker composeで初めにAzuriteを起動してました。以下がdocker composeの内容

YAML
version: '3.8'

services:
  azurite:
    image: mcr.microsoft.com/azure-storage/azurite:latest
    container_name: receiptify-azurite
    command: "azurite --blobHost 0.0.0.0 --queueHost 0.0.0.0 --tableHost 0.0.0.0 --loose --skipApiVersionCheck"
    ports:
      - "10000:10000"   # Blob service
      - "10001:10001"   # Queue service
      - "10002:10002"   # Table service
    volumes:
      - ./azurite-data:/data
    environment:
      - AZURITE_ACCOUNTS=devstoreaccount1:hogehoge
    restart: unless-stopped
    networks:
      - receiptify-network

networks:
  receiptify-network:
    driver: bridge

解決策

この問題を解決するためには、Azurite側でCORSを許可する設定を追加する必要があります。本件では、Azure CLIを用いてCORSルールを直接設定することで解決しました。

手順としては、Docker composeで先にAzuriteを起動しておき、その後に以下のスクリプトを実行します。

実行したコマンドは以下の通りです。

#!/bin/bash
az storage cors add \
  --services b \
  --methods GET POST PUT DELETE OPTIONS \
  --origins "*" \
  --allowed-headers "*" \
  --exposed-headers "*" \
  --max-age 86400 \
  --connection-string "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=hogehoge;BlobEndpoint=http://localhost:10000/devstoreaccount1;" 2>/dev/null || echo "CORS setting skipped (may already exist)"

このコマンドは、--origins "*" パラメータによって全てのオリジンからのリクエストを許可し、--methods パラメータで許可するHTTPメソッドを定義しています。開発環境においては * を使用することで迅速な開発が可能ですが、本番環境ではセキュリティの観点から、許可するオリジンを具体的に指定することが推奨されます。

また、末尾の 2>/dev/null || echo "CORS setting skipped (may already exist)" は、CORS設定が既に存在する場合にエラーメッセージが表示されることを防ぐための処理です。