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

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

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

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

يمكنك إكمال هذا البرنامج التعليمي على macOS أو Linux أو Windows.

إذا لم يكن لديك حساب 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 وثائق واجهة برمجة تطبيقات الويب الأساسية باستخدام Swagger / OpenAPI. يستخدم منشئ 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 الأساسية تعمل محليا.

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

  4. انتقل إلى http://localhost:5000 تطبيق المتصفح وجرب استخدامه. لاحقا، ستوجه تطبيق المتصفح إلى واجهة برمجة تطبيقات بعيدة في App Service لاختبار وظيفة 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:

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

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

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

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

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

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

توزيع التطبيق على Azure

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

تكوين نشر Git المحلي

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

لتكوين مستخدم النشر، قم بتشغيل الأمر az webapp deployment user set في 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 في موقع غرب أوروبا . لمشاهدة جميع المواقع المدعومة لخدمة التطبيقات في المستوى المجاني ، قم بتشغيل 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 في مستوى التسعير المجاني :

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 Service الخاص بك إلى main. (راجع تغيير فرع النشر.) في 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 ببيانات الاعتماد، تأكد من إدخال بيانات الاعتماد التي قمت بإنشائها في تكوين نشر git المحلي، وليس بيانات الاعتماد التي تستخدمها لتسجيل الدخول إلى مدخل Microsoft 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://&lt;app_name&gt;.scm.azurewebsites.net/&lt;app_name&gt;.git
* [new branch]      master -> master

استعراض الوصول إلى تطبيق Azure

  1. انتقل إلى http://<app_name>.azurewebsites.net/swagger المستعرض واعرض واجهة مستخدم Swagger.

    لقطة شاشة ASP.NET Core API قيد التشغيل في Azure App Service.

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

  3. انتقل إلى http://<app_name>.azurewebsites.net/api/todo رؤية واجهة برمجة التطبيقات المنشورة تعمل.

إضافة وظائف 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) وافحص علامة التبويب وحدة التحكم . يجب أن ترى الآن رسالة No 'Access-Control-Allow-Origin' header is present on the requested resourceالخطأ .

    لقطة شاشة لخطأ CORS في عميل المستعرض.

    يتم التعرف على عدم تطابق المجال بين تطبيق المستعرض (http://localhost:5000) والمورد البعيد (http://<app_name>.azurewebsites.net) من قبل المستعرض الخاص بك كطلب مورد عبر المنشأ. أيضا، نظرا لأن تطبيق 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. لقد اختفت رسالة الخطأ في نافذة وحدة التحكم الآن، ويمكنك مشاهدة البيانات من واجهة برمجة التطبيقات المنشورة والتفاعل معها. تدعم واجهة برمجة التطبيقات البعيدة الآن CORS لتطبيق المتصفح الذي يعمل محليًّا.

لقطة شاشة تعرض دعم CORS في عميل المستعرض.

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

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

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

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

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

إشعار

لا تحاول استخدام التطبيق خدمة CORS ورمز CORS الخاصَّين بك معًا. إذا حاولت استخدامها معا، فإن App Service 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

قد يستغرق تشغيل هذا الأمر دقيقة.

الخطوة التالية

ما تعلمته:

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

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