チュートリアル:Azure App Service で CORS を使用して RESTful API をホストする
Azure App Service は、非常にスケーラブルな、自己適用型の Web ホスティング サービスを提供します。 さらに、App Service には、RESTful API 用のクロスオリジン リソース共有 (CORS) のサポートが組み込まれています。 このチュートリアルでは、CORS サポートを使用して ASP.NET Core API アプリを App Service にデプロイする方法について説明します。 コマンドライン ツールを使用してアプリを構成し、Git を使用してアプリをデプロイします。
このチュートリアルでは、次の作業を行う方法について説明します。
- Azure CLI を使用して App Service リソースを作成する。
- Git を使用して RESTful API を Azure にデプロイする。
- App Service の CORS サポートを有効にする。
このチュートリアルは、macOS、Linux、または Windows 上で実行できます。
Azure サブスクリプションをお持ちでない場合は、開始する前に Azure 無料アカウントを作成してください。
前提条件
ローカル ASP.NET Core アプリを作成する
この手順では、ローカル ASP.NET Core プロジェクトを設定します。 App Service では、他の言語で記述された API についても同じワークフローがサポートされます。
サンプル アプリケーションの複製
ターミナル ウィンドウで
cd
を使用して作業ディレクトリに移動します。サンプル リポジトリをクローンし、リポジトリ ルートに移動します。
git clone https://github.com/Azure-Samples/dotnet-core-api cd dotnet-core-api
このリポジトリには、「Swagger/OpenAPI を使用する ASP.NET Core Web API のドキュメント」というチュートリアルに基づいて作成されたアプリが含まれています。 ここでは、Swagger ジェネレーターを使用して Swagger UI と Swagger JSON エンドポイントが提供されます。
既定のブランチが
main
であることを確認します。git branch -m main
ヒント
App Service では、ブランチ名の変更は必要ありません。 ただし、多くのリポジトリで既定のブランチが
main
に変更されているため (「デプロイ ブランチを変更する」を参照)、このチュートリアルでは、main
からリポジトリをデプロイする方法を示します。
アプリケーションの実行
次のコマンドを実行して、必要なパッケージをインストールし、データベースの移行を実行し、アプリケーションを起動します。
dotnet restore dotnet run
Swagger UI を試すには、ブラウザーで
http://localhost:5000/swagger
に移動します。http://localhost:5000/api/todo
に移動して、ToDo JSON 項目の一覧を確認します。http://localhost:5000
に移動し、ブラウザー アプリを試してみます。 後で、ブラウザー アプリで App Service のリモート API を参照して、CORS 機能をテストします。 ブラウザー アプリのコードは、リポジトリの wwwroot ディレクトリにあります。任意のタイミングで ASP.NET Core を停止するには、ターミナルで Ctrl+C キーを押します。
Azure Cloud Shell
Azure では、ブラウザーを介して使用できる対話型のシェル環境、Azure Cloud Shell がホストされています。 Cloud Shell で Bash または PowerShell を使用して、Azure サービスを操作できます。 ローカル環境に何もインストールしなくても、Cloud Shell にプレインストールされているコマンドを使用して、この記事のコードを実行できます。
Azure Cloud Shell を開始するには、以下のようにします。
オプション | 例とリンク |
---|---|
コードまたはコマンド ブロックの右上隅にある [使ってみる] を選択します。 [使ってみる] を選択しても、コードまたはコマンドは Cloud Shell に自動的にはコピーされません。 | |
https://shell.azure.com に移動するか、[Cloud Shell を起動する] ボタンを選択して、ブラウザーで Cloud Shell を開きます。 | |
Azure portal の右上にあるメニュー バーの [Cloud Shell] ボタンを選択します。 |
Azure Cloud Shell を使用するには、以下のようにします。
Cloud Shell を開始します。
コード ブロック (またはコマンド ブロック) の [コピー] ボタンを選択し、コードまたはコマンドをコピーします。
Windows と Linux では Ctrl+Shift+V キーを選択し、macOS では Cmd+Shift+V キーを選択して、コードまたはコマンドを Cloud Shell セッションに貼り付けます。
Enter キーを選択して、コードまたはコマンドを実行します。
Azure にアプリケーションをデプロイする
この手順では、App Service に .NET Core アプリケーションをデプロイします。
ローカル Git デプロイの構成
FTP およびローカルの Git では、"デプロイ ユーザー" を使用して Azure Web アプリにデプロイできます。 デプロイ ユーザーを構成すると、すべての Azure デプロイでこのユーザーを使用できます。 アカウントレベルのデプロイのユーザー名とパスワードは、Azure サブスクリプションの資格情報とは異なります。
デプロイ ユーザーを構成するには、Azure Cloud Shell で az webapp deployment user set コマンドを実行します。 <username> と <password> を、デプロイ ユーザーのユーザー名とパスワードで置き換えます。
- ユーザー名は、Azure 内で一意である必要があり、ローカル Git プッシュの場合は "\@" シンボルを含めることはできません。
- パスワードは長さが 8 文字以上で、文字、数字、記号のうち 2 つを含む必要があります。
az webapp deployment user set --user-name <username> --password <password>
JSON 出力には、パスワードが null
として表示されます。 'Conflict'. Details: 409
エラーが発生した場合は、ユーザー名を変更します。 'Bad Request'. Details: 400
エラーが発生した場合は、より強力なパスワードを使用します。
Web アプリのデプロイに使用するユーザー名とパスワードを記録します。
リソース グループを作成する
リソース グループとは、Web アプリ、データベース、ストレージ アカウントなどの Azure リソースのデプロイと管理に使用する論理コンテナーです。 たとえば、後から簡単な手順で一度にリソース グループ全体を削除することもできます。
Cloud Shell で az group create
コマンドを使用して、リソース グループを作成します。 次の例では、myResourceGroup という名前のリソース グループを "西ヨーロッパ" の場所に作成します。 Free レベルの App Service でサポートされているすべての場所を表示するには、az appservice list-locations --sku FREE
コマンドを実行します。
az group create --name myResourceGroup --location "West Europe"
通常は、現在地付近の地域にリソース グループおよびリソースを作成します。
コマンドが完了すると、リソース グループのプロパティが JSON 出力に表示されます。
App Service プランを作成する
Cloud Shell で az appservice plan create
コマンドを使用して、App Service プランを作成します。
次の例では、myAppServicePlan
価格レベルの myAppServicePlan
という名前の App Service プランを作成します。
az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku FREE
App Service プランが作成されると、Azure CLI によって、次の例のような情報が表示されます。
{ "adminSiteName": null, "appServicePlanName": "myAppServicePlan", "geoRegion": "West Europe", "hostingEnvironmentProfile": null, "id": "/subscriptions/0000-0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan", "kind": "app", "location": "West Europe", "maximumNumberOfWorkers": 1, "name": "myAppServicePlan", < JSON data removed for brevity. > "targetWorkerSizeId": 0, "type": "Microsoft.Web/serverfarms", "workerTierName": null }
Web アプリを作成する
myAppServicePlan
App Service プランで Web アプリを作成します。
Cloud Shell で、az webapp create
コマンドを使用することができます。 次の例では、<app-name>
をグローバルに一意のアプリ名に置き換えてください (有効な文字は a-z
、0-9
、-
)。
az webapp create --resource-group myResourceGroup --plan myAppServicePlan --name <app-name> --deployment-local-git
Web アプリが作成されると、Azure CLI によって次の例のような出力が表示されます。
Local git is configured with url of 'https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git' { "availabilityState": "Normal", "clientAffinityEnabled": true, "clientCertEnabled": false, "clientCertExclusionPaths": null, "cloningInfo": null, "containerSize": 0, "dailyMemoryTimeQuota": 0, "defaultHostName": "<app-name>.azurewebsites.net", "deploymentLocalGitUrl": "https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git", "enabled": true, < JSON data removed for brevity. > }
Note
Git リモートの URL は deploymentLocalGitUrl
プロパティに https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git
形式で出力されます。 この URL は後で必要になるので保存しておいてください。
Git から Azure へのプッシュ
main
ブランチをデプロイするため、App Service アプリの既定のデプロイ ブランチをmain
に設定する必要があります (「main
」を参照)。 Cloud Shell で、az webapp config appsettings set
コマンドを使用してDEPLOYMENT_BRANCH
アプリ設定を設定します。az webapp config appsettings set --name <app-name> --resource-group myResourceGroup --settings DEPLOYMENT_BRANCH='main'
ローカル ターミナル ウィンドウで、ローカル Git リポジトリに Azure リモートを追加します。 <deploymentLocalGitUrl-from-create-step>を、「Web アプリを作成する」で保存した Git リモートの URL に置き換えます。
git remote add azure <deploymentLocalGitUrl-from-create-step>
アプリをデプロイするために、次のコマンドで Azure リモートにプッシュします。 Git Credential Manager で資格情報の入力を求められたら、Azure portal へのサインインに使用する資格情報ではなく、「ローカル Git デプロイを構成する」で作成した資格情報を入力してください。
git push azure main
このコマンドの実行には数分かかることがあります。 実行中、次の例のような情報が表示されます。
Enumerating objects: 83, done.
Counting objects: 100% (83/83), done.
Delta compression using up to 8 threads
Compressing objects: 100% (78/78), done.
Writing objects: 100% (83/83), 22.15 KiB | 3.69 MiB/s, done.
Total 83 (delta 26), reused 0 (delta 0)
remote: Updating branch 'master'.
remote: Updating submodules.
remote: Preparing deployment for commit id '509236e13d'.
remote: Generating deployment script.
remote: Project file path: .\TodoApi.csproj
remote: Generating deployment script for ASP.NET MSBuild16 App
remote: Generated deployment script files
remote: Running deployment command...
remote: Handling ASP.NET Core Web Application deployment with MSBuild16.
remote: .
remote: .
remote: .
remote: Finished successfully.
remote: Running post deployment command(s)...
remote: Triggering recycle (preview mode disabled).
remote: Deployment successful.
To https://<app_name>.scm.azurewebsites.net/<app_name>.git
* [new branch] master -> master
Azure アプリを参照する
ブラウザーで
http://<app_name>.azurewebsites.net/swagger
に移動し、Swagger UI を表示します。http://<app_name>.azurewebsites.net/swagger/v1/swagger.json
に移動して、デプロイされた API の swagger.json を確認します。http://<app_name>.azurewebsites.net/api/todo
に移動して、デプロイされた API が機能していることを確認します。
CORS 機能の追加
次に、API について App Service の組み込み CORS サポートを有効にします。
サンプル アプリで CORS をテストする
ローカル リポジトリで、wwwroot/index.html を開きます。
行 51 の
apiEndpoint
変数を、デプロイされた API の URL (http://<app_name>.azurewebsites.net
) に設定します。 <app_name> は、App Service のアプリ名に置き換えます。ローカル ターミナル ウィンドウでサンプル アプリをもう一度実行します。
dotnet run
http://localhost:5000
でブラウザー アプリに移動します。 ブラウザーで開発者ツール ウィンドウを開き (Windows 用の Chrome では Ctrl+Shift+i キー)、[Console] タブを確認します。No 'Access-Control-Allow-Origin' header is present on the requested resource
というエラー メッセージが表示されています。ブラウザー アプリ (
http://localhost:5000
) とリモート リソース (http://<app_name>.azurewebsites.net
) のドメインの不一致は、クロス オリジン リソース要求としてブラウザーによって認識されます。 また、App Service アプリからAccess-Control-Allow-Origin
ヘッダーが送信されていないため、ブラウザーにはクロスドメイン コンテンツが読み込まれません。運用環境のブラウザー アプリには localhost URL ではなくパブリック URL が割り当てられますが、localhost URL に対して CORS を有効にするプロセスは、パブリック URL のプロセスと同じです。
CORS を有効にする
Cloud Shell で az webapp cors add
コマンドを使用して、クライアントの URL に対して CORS を有効にします。 <app-name> プレースホルダーを置換します。
az webapp cors add --resource-group myResourceGroup --name <app-name> --allowed-origins 'http://localhost:5000'
コマンドを複数回実行するか、--allowed-origins
にコンマ区切りリストを追加することで、許可する配信元を複数追加できます。 すべての配信元を許可するには、--allowed-origins '*'
を使用します。
CORS をもう一度テストする
http://localhost:5000
でブラウザー アプリを更新します。 [Console](コンソール) ウィンドウのエラー メッセージは消えており、デプロイされた API からのデータを確認して操作できます。 これで、ローカルで実行されているブラウザー アプリへの CORS がリモート API でサポートされました。
おめでとうございます。CORS サポートを使用して Azure App Service の API が実行されています。
よく寄せられる質問
- App Service CORS と独自の CORS
- 許可された配信元をワイルドカード サブドメインに設定する方法
- ACCESS-CONTROL-ALLOW-CREDENTIALS ヘッダーを応答で有効にする方法
App Service CORS と独自の CORS
App Service CORS ではなく独自の CORS ユーティリティを使用して、柔軟性を高めることができます。 たとえば、複数のルートまたはメソッドに対して、許可する配信元を個別に指定することができます。 App Service CORS では、すべての API ルートとメソッドに許可する配信元を 1 セットのみ指定できるため、独自の CORS コードを使用する必要があります。 ASP.NET Core で CORS を有効にする方法については、CORS の有効化に関する記事を参照してください。
組み込みの App Service CORS 機能には、指定した配信元ごとに特定の HTTP メソッドまたは動詞のみを許可するオプションはありません。 定義された配信元ごとにすべてのメソッドとヘッダーが自動的に許可されます。 この動作は、オプション .AllowAnyHeader()
と .AllowAnyMethod()
をコードで使用する場合の ASP.NET CORE CORS ポリシーに似ています。
Note
App Service CORS と独自の CORS コードを一緒に使用しないでください。 それらを併用しようとすると、App Service CORS が優先され、独自の CORS コードは機能しません。
許可された配信元をワイルドカード サブドメインに設定する方法
*.contoso.com
のようなワイルドカード サブドメインには、ワイルドカード配信元 *
よりも厳しい制限があります。 Azure portal 内にあるアプリの CORS 管理ページでは、許可する配信元としてワイルドカードのサブドメインを設定することができません。 ただし、次のように Azure CLI を使用してこれを行うことができます。
az webapp cors add --resource-group <group-name> --name <app-name> --allowed-origins 'https://*.contoso.com'
ACCESS-CONTROL-ALLOW-CREDENTIALS ヘッダーを応答で有効にする方法
Cookie や認証トークンなどの資格情報をアプリで送信する必要がある場合、ブラウザーは、応答に ACCESS-CONTROL-ALLOW-CREDENTIALS
ヘッダーを必要とします。 App Service でこれを有効にするには、properties.cors.supportCredentials
を true
に設定します。
az resource update --name web --resource-group <group-name> \
--namespace Microsoft.Web --resource-type config \
--parent sites/<app-name> --set properties.cors.supportCredentials=true
許可する配信元にワイルドカードの配信元 '*'
が含まれている場合、この操作は許可されません。 AllowAnyOrigin
と AllowCredentials
を指定することは安全ではありません。 そうすると、クロスサイト リクエスト フォージェリが発生する可能性があります。 資格情報を許可するには、ワイルドカードの配信元をワイルドカード サブドメインに置き換えてみてください。
リソースをクリーンアップする
前の手順では、リソース グループ内に Azure リソースを作成しました。 これらのリソースが将来必要になると想定していない場合、Cloud Shell で次のコマンドを実行して、リソース グループを削除します。
az group delete --name myResourceGroup
このコマンドの実行には、少し時間がかかる場合があります。
次のステップ
ここで学習した内容は次のとおりです。
- Azure CLI を使用して App Service リソースを作成する。
- Git を使用して RESTful API を Azure にデプロイする。
- App Service の CORS サポートを有効にする。
次のチュートリアルに進み、ユーザーを認証および認可する方法を学習してください。