بالنسبة لمطور متمرس، قد لا يكون هذا النص مفاجئًا على الإطلاق، لكنني أعتقد أن الكثير من المقالات التي قرأتها عن إعداد CORS في Rails كانت تقول شيئًا مثل: استخدم الرف-كورس، واسمح لأي مضيف بالوصول إلى واجهة برمجة التطبيقات، و (اختياريًا): يجب أن تفكر في شيء مختلف (عن السماح لأي مضيف) في الإنتاج.
المقترح الكود كان دائمًا قريبًا من الذي بالأسفل:
التهيئة/إنيتيليزر/كورس.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
السماح بالقيام
الأصول ''
المورد ''، الرؤوس: :أي، الطرق: :أي
نهاية
النهاية
وللأسف، كانت هذه النصوص بالكاد تشرح لنا ما يجب القيام به فعليًا في الإنتاج.
لا مشكلة لديّ في النسخ واللصق (أنا أمزح أحياناً بأن الشركات يمكن أن تستأجر ناسخاً من Stack Overflow)، بقدر ما هناك لحظة "التفكير والتعديل" بين "النسخ" و"اللصق". لذا، أود أن أوضح قليلاً ما نقوم به هنا وكيف يعمل في الحياة الواقعية.
آمل ألا تمانعوا أن أبدأ بمقدمة قصيرة عن نظرية الشرف ثم أنتقل إلى أمثلة القضبان.
مقدمة
لنبدأ من البداية. لتوضيح الأمور بشكل أفضل، قسمت المقدمة إلى ثلاثة أجزاء. الجزء الأول سيوضح ما هو الأصل - المصطلح الرئيسي لما نناقشه هنا. والجزء الثاني عن SOP، مجرد وصف موجز. والجزء الأخير يتحدث عن أجهزة الاستشعار عن بُعد
نفسها.
ما هو الأصل؟
وفقًا لمستندات الويب MDN Web Docs:
- يتم تعريف أصل محتوى الويب من خلال المخطط (البروتوكول) والمضيف (المجال) ومنفذ عنوان URL المستخدم للوصول إليه. لا يكون للكائنين نفس الأصل إلا عندما يتطابق كل من المخطط والمضيف والمنفذ (المصدر)
يبدو ذلك واضحاً جداً، أليس كذلك؟ دعونا نحلل مثالين من MDN، على سبيل المثال.
http://example.com/app1/index.html
, http://example.com/app2/index.html
2 أعلاه لهما نفس الأصل لأن:
- مخططاتهم (http) هي نفسها,
- نطاقاتها (example.com) هي نفسها,
- منافذها (الضمنية) هي نفسها.
http://www.example.com
, http://myapp.example.com
هذان أصلهما مختلفان لأن المجالين (www.example.com
, myapp.example.com
) مختلفة.
آمل أن تكون واضحة بما فيه الكفاية. إذا لم يكن كذلك، يرجى الانتقال إلى مستندات الويب MDN لمزيد من الأمثلة.
ما هي إجراءات التشغيل الموحدة؟
يقول مستندات الويب MDN Web Docs (المصدر):
- سياسة الأصل نفسه هي آلية أمان مهمة تقيد كيفية تفاعل المستند أو البرنامج النصي الذي تم تحميله من أصل واحد مع مورد من أصل آخر. وهي تساعد على عزل المستندات التي يحتمل أن تكون ضارة، مما يقلل من نواقل الهجوم المحتملة.
- عادةً ما يُسمح بالكتابات العابرة للأصول. ومن الأمثلة على ذلك الروابط وعمليات إعادة التوجيه وعمليات إرسال النماذج.
- عادةً ما يُسمح بالتضمين عبر المنشأ.
- لا يُسمح عادةً بالقراءات المتقاطعة الأصلية، ولكن غالبًا ما يتم تسريب الوصول للقراءة عن طريق التضمين.
الاستخدام أجهزة الاستشعار عن بُعد
للسماح بالوصول عبر المنشأ
حسناً، كما ترى، هناك الكثير عن السلوك العابر للأصول في تعريفات SOP. لا بأس بذلك. كل ما يجب أن نعرفه الآن هو أن نفس الأصل لديه المزيد من الامتيازات ويمكننا تخفيف القواعد الخاصة بالأصول المتقاطعة باستخدام CORS. وهنا يأتي القسم التالي.
ما هو CORS؟
استناداً إلى كلمات MDN
- مشاركة الموارد العابرة للأصول (CORS) هي آلية تستند إلى رأس HTTP تسمح للخادم بالإشارة إلى أي أصول أخرى (مجال أو مخطط أو منفذ) غير أصله الذي يجب أن يسمح المتصفح بتحميل الموارد منه. تعتمد CORS أيضًا على آلية تقوم من خلالها المتصفحات بتقديم طلب "تهيئة مسبقة" إلى الخادم الذي يستضيف المورد متعدد الأصول، وذلك للتحقق من أن الخادم سيسمح بالطلب الفعلي. في هذه التهيئة المسبقة، يرسل المتصفح رؤوساً تشير إلى طريقة HTTP والعناوين التي سيتم استخدامها في الطلب الفعلي (المصدر).
هذا لا يزال غير كافٍ. ما لم يُذكر هناك صراحةً هو أن أهم عنوان عند استخدام أجهزة الاستشعار عن بُعد
هو الوصول-التحكم-التحكم-السماح-بالأصل
:
- إن
الوصول-التحكم-التحكم-السماح-بالأصل
يشير رأس الاستجابة إلى ما إذا كان يمكن مشاركة الاستجابة مع رمز الطلب من الأصل المحدد (المصدر).
يجب أن يكون هذا كل شيء. في الحياة الواقعية، عند تكوين أجهزة الاستشعار عن بُعد
، نقوم عادةً بتهيئة المنظمة العربية للطيران المدني
الرأس أولاً.
الحياة الواقعية
هذا كل شيء عندما يتعلق الأمر بالتعريفات. لنعد إلى القضبان والأمثلة الواقعية.
كيفية تكوين CORS في Rails؟
سنستخدم حتماً الرف-كورس (كما قيل لنا). دعونا نتذكر المقتطف الأول، وهو الأكثر وروداً في المقالات الأخرى:
التهيئة/إنيتيليزر/كورس.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
السماح بالقيام
الأصول ''
المورد ''، الرؤوس: :أي، الطرق: :أي
نهاية
النهاية
عدد الخيارات كبير أو حتى لا نهائي ولكن دعنا نفكر في هذين الخيارين:
- نقوم ببناء واجهة برمجة التطبيقات المسموح باستخدامها من قبل عملاء متصفح الطرف الثالث,
- لدينا فصل نموذجي بين الواجهة الأمامية والخلفية ونريد السماح لعملائنا الموثوق بهم بالوصول إلى واجهة برمجة التطبيقات.
بناء واجهة برمجة التطبيقات (API) التي يصل إليها عملاء الطرف الثالث
إذا كنت تواجه الخيار الأول، فيمكنك على الأرجح اختيار الأصول
"*" - تريد من الآخرين بناء عميل على واجهة برمجة التطبيقات الخاصة بك، ولا تعرف من هم، أليس كذلك؟
الفصل النموذجي بين الواجهة الأمامية/الخلفية
إذا كنت تقوم بتطوير هذا الأخير، فأنت على الأرجح لا تريد أن يقوم الجميع بتقديم طلبات عبر المصدر إلى واجهة برمجة التطبيقات الخاصة بك. أنت تريد بالأحرى
- السماح لعملاء الإنتاج بالوصول إلى واجهة برمجة تطبيقات الإنتاج,
- نفس الشيء بالنسبة للتدريج,
- نفس الشيء بالنسبة للمضيف المحلي,
- قد ترغب في السماح لتطبيقات المراجعة FE بالوصول إلى التدريج.
سوف نستمر في استخدام الرفوف (كما قيل لنا) - ولكن على طريقتنا.
لنستخدم متغيرين من متغيرات ENV: الأصول_المسموح بها
لتعريفات الأصل الحرفي (علامة النجمة أو عنوان URL الفعلي) و المراجع_المسموح_بالأصل المسموح به
للأنماط.
التهيئة/إنيتيليزر/كورس.rb
متجمدة: صحيح
toregexp = -> (سلسلة) { Regexp.new(string)}
المضيفين = [
*ENV.fetch('ALLOWEDORIGORIGINS').split(','),
*ENV.fetch('ALLOWEDORIGIGINREGEXPS').split('؛').map(&to_regexp)
]
Rails.application.config.middleware.insert_before 0, Rack::Cors do
السماح بالقيام
الأصول(*المضيفات)
المورد '*',
الأساليب: %i[احصل على وظيفة وضع التصحيح حذف خيارات الرأس],
الرؤوس: :أي
نهاية
النهاية
ما الذي يحدث هنا؟
- كما ترى، نحن نقسم القيم المحددة في متغيرات ENV بفواصل مختلفة. وذلك لأن الفاصلة المنقوطة أقل احتمالًا للظهور في نمط تعريف عنوان URL.
- القيم الحرفية جاهزة للاستخدام، ولكن علينا تعيين الأنماط لتكون مثيلات Regexp فعلية.
- بعد ذلك، نحن نضم كل شيء معًا ونسمح لهؤلاء المضيفين بالوصول إلى أي مورد باستخدام أساليب مدرجة في القائمة البيضاء التي تستخدمها واجهة برمجة التطبيقات الخاصة بنا.
من المفترض أن يمنحك هذا مرونة كافية لتحديد القيم المناسبة في بيئات التطوير والتدريج والإنتاج.
الاستنتاجات
دعونا نلخص كل ما سبق في نقاط رئيسية:
- استخدام متغيرات ENV لتهيئة
أجهزة الاستشعار عن بُعد
,
- استخدام التعبيرات العادية للسماح للأصول المختلفة بالوصول إلى واجهة برمجة التطبيقات المرحلية (على سبيل المثال، لمراجعة التطبيقات),
- ضع دائمًا "فكر واضبط" بين "نسخ" و"لصق".
هذا كل شيء. طاب يومك 🙂
اقرأ المزيد:
لماذا يجب عليك (على الأرجح) استخدام Typescript؟
10 شركات ناشئة في مدينة نيويورك تستحق الذكر في 2021