教學課程:在 Azure App Service 中裝載具有 CORS 支援的 RESTful API
Azure App Service 提供可高度調整、自我修復的 Web 裝載服務。 此外,App Service 有 RESTful API 的內建跨原始資源共用 (CORS) 支援。 本教學課程示範如何將 ASP.NET Core API 應用程式部署至具有 CORS 支援的 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
在瀏覽器中瀏覽至
http://localhost:5000/swagger
以試用 Swagger UI。瀏覽至
http://localhost:5000/api/todo
以查看 ToDo JSON 項目的清單。瀏覽至
http://localhost:5000
以實驗瀏覽器應用程式。 稍後,您會將瀏覽器應用程式指向 App Service 中的遠端 API,以測試 CORS 功能。 瀏覽器應用程式的程式碼位於存放庫的 wwwroot 目錄中。如需隨時停止 ASP.NET Core,請在終端機上選取 [Ctrl+C]。
Azure Cloud Shell
Azure Cloud Shell 是裝載於 Azure 中的互動式殼層環境,可在瀏覽器中使用。 您可以使用 Bash 或 PowerShell 搭配 Cloud Shell,與 Azure 服務共同使用。 您可以使用 Cloud Shell 預先安裝的命令,執行本文提到的程式碼,而不必在本機環境上安裝任何工具。
要啟動 Azure Cloud Shell:
選項 | 範例/連結 |
---|---|
選取程式碼或命令區塊右上角的 [試試看]。 選取 [試試看] 並不會自動將程式碼或命令複製到 Cloud Shell 中。 | |
請前往 https://shell.azure.com,或選取 [啟動 Cloud Shell] 按鈕,在瀏覽器中開啟 Cloud Shell。 | |
選取 Azure 入口網站右上方功能表列上的 [Cloud Shell] 按鈕。 |
若要使用 Azure Cloud Shell:
啟動 Cloud Shell。
選取程式碼區塊 (或命令區塊) 上的 [複製] 按鈕以複製程式碼或命令。
透過在 Windows 和 Linux 上選取 Ctrl+Shift+V;或在 macOS 上選取 Cmd+Shift+V,將程式碼或命令貼到 Cloud Shell 工作階段中。
選取 Enter 鍵執行程式碼或命令。
將應用程式部署至 Azure
在此步驟中,您會將 .NET Core 應用程式部署至 App Service。
設定本機 Git 部署
FTP 和本機 Git 可以透過使用「部署使用者」部署到 Azure Web 應用程式。 部署使用者只需設定一次,就能供所有 Azure 部署使用。 使用者名稱和密碼屬於帳戶等級部署,因此與 Azure 訂用帳戶認證不同。
若要設定部署使用者,請在 Azure Cloud Shell 中執行 az webapp deployment user set 命令。 將 <username> 和 <password> 取代為部署使用者的使用者名稱和密碼。
- 使用者名稱在 Azure 服務及本機 Git 推送中都必須是唯一的,且不能包含 ‘@’ 符號。
- 密碼長度必須至少為 8 個字元,包含下列三個元素其中兩個:字母、數字及符號。
az webapp deployment user set --user-name <username> --password <password>
JSON 輸出會將密碼顯示為 null
。 如果您收到 'Conflict'. Details: 409
錯誤,請變更使用者名稱。 如果您收到 'Bad Request'. Details: 400
錯誤,請使用更強的密碼。
將使用者名稱和密碼記錄下來,在部署 Web 應用程式時還會用到。
建立資源群組
資源群組是一個邏輯容器,可在其中部署與管理 Azure 資源 (例如 Web 應用程式、資料庫和儲存體帳戶)。 例如,您可以選擇在稍候透過一個簡單的步驟刪除整個資源群組。
在 Cloud Shell 中,使用 az group create
命令來建立資源群組。 下列範例會在「西歐」位置建立名為 myResourceGroup 的資源群組。 若要查看免費層中支援 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
的 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
命令。 在下列範,了中,使用全域唯一的應用程式名稱 (有效的字元為 a-z
、0-9
和 -
) 取代 <app-name>
。
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. > }
注意
Git 遠端的 URL 會顯示在 deploymentLocalGitUrl
屬性中,其格式為 https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git
。 儲存此 URL,稍後您會用到此資訊。
從 Git 推送至 Azure
由於您要部署
main
分支,因此必須將 App Service 應用程式的預設部署分支設定為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'
回到本機終端視窗,將 Azure 遠端新增至本機 Git 存放庫。 將 <deploymentLocalGitUrl-from-create-step> 取代為您從建立 Web 應用程式儲存的 Git 遠端 URL。
git remote add azure <deploymentLocalGitUrl-from-create-step>
推送到 Azure 遠端,使用下列命令來部署您的應用程式。 當 Git 認證管理員提示您輸入認證時,請確實輸入您在 [設定本機 git 部署] 中建立的認證,而不是您用來登入 Azure 入口網站的認證。
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 功能
接著,您會在 App Service 中為 API 啟用內建 CORS 支援。
在範例應用程式中測試 CORS
在您的本機存放庫中,開啟 wwwroot/index.html。
在第 51 行中,將
apiEndpoint
變數設定為已部署 API 的 URL (http://<app_name>.azurewebsites.net
)。 以您在 App Service 中的應用程式名稱取代 <appname>。在您的本機終端機視窗中,再次執行範例應用程式。
dotnet run
瀏覽至位於
http://localhost:5000
的瀏覽器應用程式。 在瀏覽器中開啟 [開發人員工具] 視窗 (在適用於 Windows 的 Chrome 中按 [Ctrl+Shift+i]),並檢查 [主控台] 索引標籤。您現在會看到錯誤訊息:No 'Access-Control-Allow-Origin' header is present on the requested resource
。在瀏覽器應用程式 (
http://localhost:5000
) 與遠端資源 (http://<app_name>.azurewebsites.net
) 之間的網域不相符,會由您的瀏覽器辨識為跨來源資源要求。 此外,由於 API App Service 應用程式未傳送Access-Control-Allow-Origin
標頭,瀏覽器已禁止載入跨網域內容。在生產環境中,瀏覽器應用程式會有公用 URL (而非 localhost 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
的瀏覽器應用程式。 [主控台] 視窗中的錯誤訊息現已消失,而且您可看到來自已部署 API 的資料並與其互動。 您的遠端 API 現在對在本機執行的瀏覽器應用程式支援 CORS。
恭喜,您正在 Azure App Service 中執行具有 CORS 支援的 API。
常見問題集
App Service CORS 與您的 CORS
您可使用自己的 CORS 公用程式,而不是使用 App Service CORS,以獲得更大彈性。 例如,您可以針對不同的路由或方法,指定不同的允許來源。 由於 App Service CORS 讓您針對所有的 API 路由和方法只指定一組可接受的來源,因此您可使用自己的 CORS 程式碼。 請參閱在啟用 CORS的 ASP.NET Core 中啟用 CORS 的方式。
內建 App Service CORS 功能沒有選項僅允許您指定的每個來源使用特定的 HTTP 方法或動詞。 它會自動允許每個定義來源的所有方法和標頭。 此行為類似於在程式碼中使用選項 .AllowAnyHeader()
和 .AllowAnyMethod()
時的 ASP.NET Core CORS 原則。
注意
請勿嘗試同時使用 App Service CORS 與您自己的 CORS 程式碼。 若嘗試一起使用它們,App Service CORS 具有優先權,而您自己的 CORS 程式碼則沒有任何作用。
如何將允許的來源設定為萬用字元子網域?
如 *.contoso.com
的萬用字元子網域比萬用字元來源 *
還要嚴格。 Azure 入口網站中應用程式的 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 支援。
移至下一個教學課程,以了解如何為使用者驗證和進行授權。