العربية

اكشف أسرار سياسة CORS (مشاركة الموارد عبر المصادر) وتعلم كيفية تمكين الطلبات عبر النطاقات بأمان في تطبيقات الويب الخاصة بك. يغطي هذا الدليل الشامل كل شيء من الأساسيات إلى الإعدادات المتقدمة.

إزالة الغموض عن سياسة CORS: دليل شامل لمشاركة الموارد عبر المصادر

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

ما هي سياسة المصدر الواحد؟

قبل الخوض في تفاصيل CORS، من المهم فهم سياسة المصدر الواحد (SOP). تعد SOP آلية أمان أساسية يتم تطبيقها في متصفحات الويب. والغرض منها هو منع النصوص البرمجية الخبيثة على موقع ويب من الوصول إلى البيانات الحساسة على موقع ويب آخر. يتم تعريف المصدر من خلال مجموعة من البروتوكول (مثل HTTP أو HTTPS)، والنطاق (مثل example.com)، ورقم المنفذ (مثل 80 أو 443). يعتبر عنوانا URL من نفس المصدر إذا كانا يشتركان في نفس البروتوكول والنطاق والمنفذ.

مثال:

تقيد سياسة المصدر الواحد (SOP) النصوص البرمجية من الوصول إلى الموارد من مصدر مختلف ما لم يتم اتخاذ تدابير محددة، مثل CORS، للسماح بذلك.

لماذا تُعد سياسة CORS ضرورية؟

بينما تعد سياسة المصدر الواحد حيوية للأمان، إلا أنها يمكن أن تكون مقيدة أيضًا. تعتمد العديد من تطبيقات الويب الحديثة على جلب البيانات من خوادم مختلفة، مثل واجهات برمجة التطبيقات (APIs) أو شبكات توصيل المحتوى (CDNs). توفر CORS طريقة محكومة لتخفيف قيود SOP والسماح بالطلبات المشروعة عبر المصادر مع الحفاظ على الأمان.

لنفترض سيناريو يحتاج فيه تطبيق ويب مستضاف على http://example.com إلى جلب بيانات من خادم واجهة برمجة تطبيقات مستضاف على http://api.example.net. بدون CORS، سيحظر المتصفح هذا الطلب بسبب سياسة SOP. تسمح CORS لخادم واجهة برمجة التطبيقات بتحديد المصادر المسموح لها بالوصول إلى موارده بشكل صريح، مما يمكن تطبيق الويب من العمل بشكل صحيح.

كيف تعمل سياسة CORS: الأساسيات

تعمل CORS من خلال سلسلة من ترويسات HTTP المتبادلة بين العميل (المتصفح) والخادم. يستخدم الخادم هذه الترويسات لإبلاغ المتصفح بما إذا كان مسموحًا له بالوصول إلى المورد المطلوب. ترويسة HTTP الرئيسية المعنية هي Access-Control-Allow-Origin.

السيناريو 1: الطلب البسيط

الطلب "البسيط" هو طلب GET، أو HEAD، أو POST يفي بمعايير محددة (على سبيل المثال، تكون قيمة ترويسة Content-Type هي واحدة من application/x-www-form-urlencoded، أو multipart/form-data، أو text/plain). في هذه الحالة، يرسل المتصفح الطلب مباشرة إلى الخادم، ويستجيب الخادم بترويسة Access-Control-Allow-Origin.

طلب العميل (من http://example.com):

GET /data HTTP/1.1
Host: api.example.net
Origin: http://example.com

استجابة الخادم (من http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json

{
  "data": "Some data from the server"
}

في هذا المثال، يستجيب الخادم بـ Access-Control-Allow-Origin: http://example.com، مما يشير إلى أن الطلبات من http://example.com مسموح بها. إذا لم يتطابق المصدر في الطلب مع القيمة الموجودة في ترويسة Access-Control-Allow-Origin (أو إذا كانت الترويسة غير موجودة)، فسيقوم المتصفح بحظر الاستجابة ومنع النص البرمجي من جانب العميل من الوصول إلى البيانات.

السيناريو 2: الطلب التمهيدي (للطلبات المعقدة)

بالنسبة للطلبات الأكثر تعقيدًا، مثل تلك التي تستخدم أساليب HTTP مثل PUT، أو DELETE، أو تلك التي تحتوي على ترويسات مخصصة، يقوم المتصفح بإجراء طلب "تمهيدي" (preflight) باستخدام أسلوب HTTP OPTIONS. يطلب هذا الطلب التمهيدي الإذن من الخادم قبل إرسال الطلب الفعلي. يستجيب الخادم بترويسات تحدد الأساليب والترويسات والمصادر المسموح بها.

طلب العميل التمهيدي (من http://example.com):

OPTIONS /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header

استجابة الخادم (من http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET, PUT, DELETE
Access-Control-Allow-Headers: X-Custom-Header, Content-Type
Access-Control-Max-Age: 3600

شرح الترويسات:

إذا أشارت استجابة الخادم التمهيدية إلى أن الطلب مسموح به، يتابع المتصفح الطلب الفعلي. وإلا، يقوم المتصفح بحظر الطلب.

طلب العميل الفعلي (من http://example.com):

PUT /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
X-Custom-Header: some-value
Content-Type: application/json

{
  "data": "Some data to be updated"
}

استجابة الخادم (من http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json

{
  "status": "Data updated successfully"
}

ترويسات CORS الشائعة

فيما يلي تفصيل لترويسات CORS الرئيسية التي تحتاج إلى فهمها:

سياسة CORS في لغات البرمجة من جانب الخادم المختلفة

يتضمن تطبيق CORS عادةً تكوين تطبيقك من جانب الخادم لإرسال ترويسات CORS المناسبة. فيما يلي أمثلة لكيفية القيام بذلك في لغات وأطر عمل مختلفة:

Node.js مع Express

يمكنك استخدام حزمة الوسيط cors:

const express = require('express');
const cors = require('cors');

const app = express();

// Enable CORS for all origins (USE WITH CAUTION IN PRODUCTION)
app.use(cors());

// Alternatively, configure CORS for specific origins
// app.use(cors({
//   origin: 'http://example.com'
// }));

app.get('/data', (req, res) => {
  res.json({ message: 'This is CORS-enabled for all origins!' });
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Python مع Flask

يمكنك استخدام ملحق Flask-CORS:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

# Alternatively, configure CORS for specific origins
# CORS(app, resources={r"/api/*": {"origins": "http://example.com"}})

@app.route("/data")
def hello():
    return {"message": "This is CORS-enabled for all origins!"}

if __name__ == '__main__':
    app.run(debug=True)

Java مع Spring Boot

يمكنك تكوين CORS في تطبيق Spring Boot الخاص بك باستخدام التعليقات التوضيحية أو فئات التكوين:

باستخدام التعليقات التوضيحية:

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@CrossOrigin(origins = "http://example.com") // Allow requests from http://example.com
public class DataController {

    @GetMapping("/data")
    public String getData() {
        return "This is CORS-enabled for http://example.com!";
    }
}

باستخدام التكوين:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/data")
                .allowedOrigins("http://example.com") // Allow requests from http://example.com
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*");
    }
}

PHP

 "This is CORS-enabled for http://example.com!");
echo json_encode($data);
?>

سياسة CORS والاعتبارات الأمنية

بينما تُمكّن CORS الطلبات عبر المصادر، فمن الضروري تطبيقها بشكل آمن. فيما يلي بعض الاعتبارات المهمة:

استكشاف أخطاء CORS وإصلاحها

قد يكون تصحيح أخطاء CORS محبطًا. فيما يلي بعض المشكلات الشائعة وكيفية حلها:

أدوات تصحيح الأخطاء:

سيناريوهات CORS المتقدمة

بينما تعتبر مفاهيم CORS الأساسية مباشرة نسبيًا، هناك بعض السيناريوهات الأكثر تقدمًا التي يجب مراعاتها:

أفضل ممارسات CORS

لضمان تنفيذ CORS آمن وفعال، اتبع أفضل الممارسات التالية:

الخاتمة

تعد CORS آلية أمان حاسمة تُمكّن الطلبات الخاضعة للرقابة عبر المصادر في تطبيقات الويب. إن فهم كيفية عمل CORS وكيفية تكوينها بشكل صحيح أمر ضروري لكل مطور ويب. باتباع الإرشادات وأفضل الممارسات الموضحة في هذا الدليل الشامل، يمكنك بناء تطبيقات ويب آمنة وفعالة تتفاعل بسلاسة مع الموارد من مصادر مختلفة.

تذكر دائمًا إعطاء الأولوية للأمان وتجنب استخدام تكوينات CORS المتساهلة بشكل مفرط. من خلال النظر بعناية في الآثار الأمنية لإعدادات CORS الخاصة بك، يمكنك حماية تطبيقاتك وبياناتك من الوصول غير المصرح به.

نأمل أن يكون هذا الدليل قد ساعدك في إزالة الغموض عن CORS. نتمنى لك برمجة ممتعة!