البرنامج التعليمي: استضافة API RESTful مع CORS في خدمة التطبيقات Azure

توفر خدمة تطبيقات Azure خدمة استضافة ويب قابلة للتطوير بدرجة كبيرة وذاتية التصحيح. وبالإضافة إلى ذلك، خدمة التطبيقات بها دعم مدمج لتبادل الموارد عبر المنشأ (CORS) لواجهات برمجة التطبيقات RESTful. يوضح هذا البرنامج التعليمي كيفية نشر تطبيق API أساسي ASP.NET إلى خدمة التطبيقات بدعم CORS. يمكنك تكوين التطبيق باستخدام أدوات سطر الأوامر ونشر التطبيق باستخدام Git.

في هذا البرنامج التعليمي، تتعلم كيفية:

  • إنشاء موارد خدمة التطبيقات باستخدام Azure CLI
  • نشر واجهة برمجة تطبيقات RESTful إلى Azure باستخدام Git
  • تمكين دعم CORS لخدمة التطبيقات

يمكنك اتباع الخطوات في هذا البرنامج التعليمي على macOS، Linux، Windows.

إذا لم يكن لديك اشتراك في Azure، فأنشئ حساب Azure مجاني قبل أن تبدأ.

المتطلبات الأساسية

لإكمال هذا البرنامج التعليمي:

قم بإنشاء تطبيق ASP.NET Core محلي

في هذه الخطوة، يمكنك إعداد المشروع الأساسي ASP.NET المحلي. تدعم خدمة التطبيقات نفس سير العمل للـ APIs المكتوبة بلغات أخرى.

استنساخ نموذج التطبيق

  1. في نافذة المحطة الطرفية، cd إلى دليل عمل.

  2. استنسخ مستودع العينة وقم بتغييره إلى جذر المستودع.

    git clone https://github.com/Azure-Samples/dotnet-core-api
    cd dotnet-core-api
    

    يحتوي هذا المستودع على تطبيق تم إنشاؤه استنادًا إلى البرنامج التعليمي التالي: ASP.NET صفحات مساعدة Core Web API باستخدام Swagger. ويستخدم مولد Swagger لخدمة واجهة المستخدم Swagger ونقطة النهاية Swagger JSON.

  3. تأكد من أن الفرع الافتراضي هو main.

    git branch -m main
    

    تلميح

    لا تتطلب App Service تغيير اسم الفرع. ومع ذلك،‏ نظرا لأن العديد من المستودعات تقوم بتغيير فرعها الافتراضي إلى main(راجع تغيير فرع النشر)،‏ فإن هذا البرنامج التعليمي يوضح لك أيضا كيفية نشر مستودع من main.

شغّل التطبيق

  1. تشغيل الأوامر التالية لتثبيت الحزم المطلوبة مع بدء تشغيل التطبيق.

    dotnet restore
    dotnet run
    
  2. قم بالانتقال إلى http://localhost:5000/swagger في مستعرض لتجربة واجهة المستخدم Swagger.

    ASP.NET Core API يعمل محليًا

  3. قم بالانتقال إلى http://localhost:5000/api/todo قائمة عناصر ToDo JSON واطلع عليها.

  4. قم بالانتقال إلى http://localhost:5000 وجرب تطبيق المتصفح. لاحقًا، ستقوم بتوجيه تطبيق المتصفح إلى واجهة برمجة تطبيقات بعيدة في خدمة التطبيقات لاختبار وظائف CORS. تم العثور على رمز لتطبيق المتصفح في دليل wwwroot الخاص بالمستودع.

  5. لإيقاف ASP.NET Core، اضغط Ctrl+C في المحطة الطرفية.

Azure Cloud Shell

Azure يستضيف Azure Cloud Shell، بيئة تفاعلية يمكن استخدامها من خلال المستعرض. يمكنك استخدام Bash أو PowerShell مع Cloud Shell للعمل مع خدمات Azure. يمكنك استخدام أوامر Cloud Shell المثبتة مسبقًا لتشغيل التعليمات البرمجية في هذه المقالة دون الحاجة إلى تثبيت أي شيء على البيئة المحلية.

لبدء Azure Cloud Shell:

خيار مثال/ رابط
انقر فوق ⁧⁩جربه⁧⁩ في الزاوية العلوية اليسرى من التعليمة البرمجية أو كتلة الأمر. تحديد ⁧⁩جربه⁧⁩ لا يقوم بنسخ التعليمة البرمجية أو الأمر تلقائيًا إلى Cloud Shell. لقطة شاشة تعرض مثالاً على Try It for Azure Cloud Shell.
انتقل إلى ⁧⁩⁧ https://shell.azure.com⁩⁧⁩، أو حدد زر ⁩تشغيل Cloud Shell لفتح Cloud Shell في المتصفح لديك. زر لتشغيل Azure Cloud Shell.
حدد زر Cloud Shell على شريط القوائم في أعلى اليمين في مدخل Microsoft Azure. لقطة شاشة تعرض زر Cloud Shell في مدخل Microsoft Azure

لاستخدام Azure Cloud Shell:

  1. ابدأ تشغيل Cloud Shell.

  2. حدد الزر نسخ على كتلة التعليمات البرمجية (أو كتلة الأوامر) لنسخ التعليمات البرمجية أو الأمر.

  3. ألصق التعليمة البرمجية أو الأمر في جلسة Cloud Shell بتحديد Ctrl+Shift+Vعلى Windows وLunix، أو بتحديد Cmd+Shift+Vعلى macOS.

  4. حدد Enter لتشغيل التعليمات البرمجية أو الأمر.

نشر تطبيق لـ Azure

في هذه الخطوة، تقوم بنشر تطبيق .NET Core في خدمة التطبيقات.

تهيئة نشر تطبيق Git المحلي

يمكن لـ FTP وGit النشر على تطبيق موقع Azure باستخدام مستخدم نشر. بمجرد تكوين مستخدم النشر الخاص بك، يمكنك استخدامه لكافة عمليات نشر Azure الخاصة بك. يختلف اسم مستخدم وكلمة مرور التوزيع على مستوى الحساب عن بيانات اعتماد اشتراك Azure الخاصة بك.

لتكوين مستخدم التوزيع، قم بتشغيل مجموعة مستخدم توزيع az webapp باستخدام الأمر في Azure Cloud Shell. استبدل <اسم المستخدم> و< كلمة المرور> باسم مستخدم التوزيع وكلمة مروره.

  • يجب أن يكون اسم المستخدم فريدًا في Azure، ولا يجب أن يحتوي دفع Git المحلي على رمز ’@‘.
  • يجب أن يكون طول كلمة المرور ثمانية أحرف على الأقل، مع اثنين من العناصر الثلاثة التالية: الأحرف والأرقام والرموز.
az webapp deployment user set --user-name <username> --password <password>

يظهر إخراج JSON كلمة المرور كـ null. إذا واجهت خطأ، قم بتغيير 'Conflict'. Details: 409 اسم المستخدم. إذا واجهت خطأ 'Bad Request'. Details: 400، فاستخدم كلمة مرور أقوى.

سجل اسم المستخدم وكلمة المرور لاستخدامها لتوزيع تطبيقات الويب الخاصة بك.

إنشاء مجموعة موارد

مجموعة الموارد هي حاوية منطقية يتم فيها نشر موارد Azure وإدارتها، مثل تطبيقات الويب وقواعد البيانات وحسابات التخزين. على سبيل المثال، يمكنك اختيار حذف مجموعة الموارد بأكملها في خطوة واحدة بسيطة لاحقاً.

في Cloud Shell، أنشئ مجموعة موارد باستخدام الأمر az group create. ينشئ المثال التالي مجموعة موارد باسم myResourceGroup في موقع West Europe. لرؤية جميع المواقع المدعومة لخدمة التطبيقات في المستوى المجاني، قم بتشغيل az appservice list-locations --sku FREE الأمر.

az group create --name myResourceGroup --location "West Europe"

يمكنك بشكل عام إنشاء مجموعة مواردك والموارد في منطقة قريبة منك.

عند انتهاء الأمر، يظهر لك إخراج JSON خصائص مجموعة الموارد.

إنشاء خطة App Service

في Cloud Shell، أنشئ خطة خدمة التطبيق باستخدام الأمر az appservice plan create.

ينشئ المثال التالي خطة App ServicemyAppServicePlan المسماة في طبقة التسعيرالمجاني:

az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku FREE

عند إنشاء خطة خدمة التطبيق، يعرض 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
} 

أنشئ تطبيق ويب

إنشاء تطبيق ويب في myAppServicePlan خطة App Service.

في 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

عند إنشاء تطبيق ويب، يعرض 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. >
}

إشعار

يظهر عنوان URL الخاص ببرنامج Git عن بعد في الخاصية deploymentLocalGitUrl، مع التنسيق https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git. احفظ عنوان URL هذا حيث تحتاج إليه لاحقًا.

انتقال إلى Azure من Git

  1. نظرًا لأنك تقوم بنشرmain الفرع، فأنت بحاجة إلى تعيين فرع النشر الافتراضي لتطبيقي App Servicemain(انظر تغيير فرع النشر). في Cloud Shell، اضبطDEPLOYMENT_BRANCH إعداد التطبيق باستخدامaz webapp config appsettings setالأمر.

    az webapp config appsettings set --name <app-name> --resource-group myResourceGroup --settings DEPLOYMENT_BRANCH='main'
    
  2. سابقاً في النافذة النهائية، أضف جهاز تحكم عن بعد لـ Azure إلى مستودع Git المحلي. استبدل <deploymentLocalGitUrl-from-create-step> بعنوان URL من جهاز Git للتحكم عن بعد الذي حفظته من إنشاء تطبيق ويب.

    git remote add azure <deploymentLocalGitUrl-from-create-step>
    
  3. اضغط على جهاز التحكم عن بعد Azure لنشر التطبيق الخاص بك مع الأمر التالي. عندما تطالبك "Git Credential Manager" ببيانات الاعتماد، تأكد من إدخال بيانات الاعتماد التي قمت بإنشائها في تكوين مستخدم نشر، وليس بيانات الاعتماد التي تستخدمها لتسجيل الدخول إلى مدخل 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

  1. قم بالانتقال إلى http://<app_name>.azurewebsites.net/swagger في مستعرض وتجربة Swagger UI.

    ASP.NET API الأساسية قيد التشغيل في خدمة التطبيقات Azure

  2. قم بالانتقال إلى http://<app_name>.azurewebsites.net/swagger/v1/swagger.json لرؤية swagger.json API المنشورة.

  3. انتقل إلى http://<app_name>.azurewebsites.net/api/todo لمشاهدة API المنشورة تعمل.

إضافة وظائف CORS

بعد ذلك، يمكنك تمكين الدعم المدمج في CORS في خدمة التطبيقات لواجهة برمجة التطبيقات الخاصة بك.

اختبار CORS في نموذج التطبيق

  1. في المستودع المحلي، افتح wwwroot/index.html.

  2. في السطر 51، قم بتعيين المتغير apiEndpoint إلى عنوان URL لواجهة برمجة التطبيقات المنشورة (http://<app_name>.azurewebsites.net). قم باستبدال <اسم التطبيق> باسم التطبيق الخاص بك في خدمة التطبيقات.

  3. في إطار المحطة الطرفية المحلية، قم بتشغيل نموذج التطبيق مرة أخرى.

    dotnet run
    
  4. قم بالانتقال إلى تطبيق المتصفح في http://localhost:5000. قم بفتح نافذة أدوات المطور في متصفحك Ctrl+Shift+i (في Chrome Windows) وافحص علامة التبويب Console. يجب أن تشاهد الآن رسالة الخطأ، No 'Access-Control-Allow-Origin' header is present on the requested resource.

    خطأ CORS في عميل المستعرض

    يتم التعرف على عدم تطابق المجال بين تطبيق المستعرض (http://localhost:5000) والمورد البعيد (http://<app_name>.azurewebsites.net) من قبل المستعرض الخاص بك كطلب مورد عبر المنشأ. أيضا، حقيقة أن واجهة برمجة تطبيقات REST الخاصة بك تطبيق App Service لا يرسل Access-Control-Allow-Origin العنوان، فقد منع المستعرض تحميل المحتوى عبر المجالات.

    في الإنتاج، سيكون لتطبيق المتصفح عنوان URL عام بدلاً من عنوان URL المضيف المحلي، ولكن طريقة تمكين CORS إلى عنوان URL للمضيف المحلي هي نفس عنوان URL العام.

تمكين CORS

في Cloud Shell، قم بتمكين CORS لعنوان URL لعميلك باستخدام الأمر az webapp cors add. استبدل العنصر النائب <اسم التطبيق>.

az webapp cors add --resource-group myResourceGroup --name <app-name> --allowed-origins 'http://localhost:5000'

يمكنك إضافة أصول متعددة مسموح بها عن طريق تشغيل الأمر عدة مرات أو عن طريق إضافة قائمة منفصلة بفاصلة في --allowed-origins. للسماح بجميع الأصول، استخدم --allowed-origins '*'.

اختبار CORS مرة أخرى

قم بتحديث تطبيق المتصفح في http://localhost:5000. رسالة الخطأ في إطار وحدة التحكم الآن ذهبت، ويمكنك مشاهدة البيانات من API المنشورة والتفاعل معها. تدعم واجهة برمجة التطبيقات البعيدة الآن CORS لتطبيق المتصفح الذي يعمل محليًّا.

نجاح CORS في عميل المستعرض

تهانينا، أنت تقوم بتشغيل واجهة برمجة تطبيقات في خدمة تطبيقات Azure بدعم CORS.

الأسئلة الشائعة

خدمة التطبيقات CORS مقابل CORS الخاص بك

يمكنك استخدام الأدوات المساعدة CORS الخاصة بك بدلًا من التطبيق خدمة CORS لمزيد من المرونة. على سبيل المثال، قد تحتاج إلى تحديد أصول مختلفة مسموح بها لطرق أو أساليب مختلفة. نظرًا لأن تطبيق الخدمة CORS يتيح لك تحديد مجموعة واحدة من الأصول المقبولة لجميع مسارات API وأساليبها، فأنت تريد استخدام رمز CORS الخاص بك. انظر كيف يفعل ASP.NET Core ذلك في تمكين طلبات عبر المنشأ (CORS).

لا تحتوي ميزة App Service CORS المضمنة على خيارات للسماح بأساليب أو أفعال HTTP معينة فقط لكل أصل تحدده. سيسمح تلقائيا بجميع الأساليب والعناوين لكل أصل معرف. يشبه هذا السلوك ASP.NET نهج CORS الأساسية عند استخدام الخيارات .AllowAnyHeader() وفي .AllowAnyMethod() التعليمات البرمجية.

إشعار

لا تحاول استخدام التطبيق خدمة CORS ورمز CORS الخاصَّين بك معًا. عند استخدامهما معًا، فإن التطبيق خدمة CORS ستكون له الأسبقية، ولن يكون لرمز CORS الخاص بك أي تأثير.

كيف أعمل تعيين الأصول المسموح بها إلى مجال فرعي لأحرف البدل؟

المجال الفرعي لحرف البدل مثل *.contoso.com أكثر تقييدا من أصل *حرف البدل . ومع ذلك، لا تتيح لك صفحة إدارة CORS الخاصة بالتطبيق في مدخل Microsoft Azure تعيين مجال فرعي لأحرف البدل كأصل مسموح به. ومع ذلك، يمكنك القيام بذلك باستخدام Azure CLI، مثل ذلك:

az webapp cors add --resource-group <group-name> --name <app-name> --allowed-origins 'https://*.contoso.com'

كيف أعمل تمكين عنوان ACCESS-CONTROL-ALLOW-CREDENTIALS على الاستجابة؟

إذا كان التطبيق يتطلب إرسال بيانات اعتماد مثل ملفات تعريف الارتباط أو رموز المصادقة المميزة، فقد يتطلب المستعرض رأس 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
  • نشر واجهة برمجة تطبيقات RESTful إلى Azure باستخدام Git
  • تمكين دعم CORS لخدمة التطبيقات

تقدم إلى البرنامج التعليمي التالي لمعرفة كيفية مصادقة المستخدمين وتفويضهم.