עברית

גלו את סודות ה-CORS (שיתוף משאבים בין מקורות) ולמדו כיצד לאפשר בקשות חוצות-דומיינים באופן מאובטח באפליקציות הרשת שלכם. מדריך מקיף זה מכסה הכל, מהיסודות ועד לתצורות מתקדמות, ומבטיח תקשורת חלקה ומאובטחת בין מקורות שונים.

הסרת המסתורין מ-CORS: מדריך מקיף לשיתוף משאבים בין מקורות

ברשת המקושרת של ימינו, אפליקציות נדרשות לעיתים קרובות לגשת למשאבים ממקורות שונים. כאן נכנס לתמונה מנגנון שיתוף המשאבים בין מקורות (CORS). CORS הוא מנגנון אבטחה חיוני הקובע כיצד דפדפני אינטרנט מטפלים בבקשות ממקור אחד (דומיין, פרוטוקול ופורט) למקור אחר. הבנת CORS חיונית לכל מפתח ווב כדי לבנות יישומי רשת מאובטחים ופונקציונליים.

מהי מדיניות אותו מקור (Same-Origin Policy)?

לפני שצוללים ל-CORS, חשוב להבין את מדיניות אותו מקור (SOP). ה-SOP הוא מנגנון אבטחה בסיסי המיושם בדפדפני אינטרנט. מטרתו היא למנוע מסקריפטים זדוניים באתר אחד לגשת למידע רגיש באתר אחר. מקור מוגדר על ידי השילוב של הפרוטוקול (למשל, HTTP או HTTPS), הדומיין (למשל, example.com), ומספר הפורט (למשל, 80 או 443). שתי כתובות URL נחשבות כבעלות אותו מקור אם הן חולקות את אותו פרוטוקול, דומיין ופורט.

דוגמה:

ה-SOP מגביל סקריפטים מגישה למשאבים ממקור שונה, אלא אם כן קיימים אמצעים ספציפיים, כמו CORS, המאפשרים זאת.

מדוע CORS נחוץ?

בעוד שמדיניות אותו מקור חיונית לאבטחה, היא יכולה גם להיות מגבילה. יישומי רשת מודרניים רבים מסתמכים על אחזור נתונים משרתים שונים, כגון ממשקי API או רשתות להעברת תוכן (CDNs). CORS מספק דרך מבוקרת להרפות מה-SOP ולאפשר בקשות לגיטימיות בין מקורות שונים תוך שמירה על אבטחה.

חשבו על תרחיש שבו יישום רשת המתארח ב-http://example.com צריך לאחזר נתונים משרת API המתארח ב-http://api.example.net. ללא CORS, הדפדפן היה חוסם בקשה זו בשל ה-SOP. CORS מאפשר לשרת ה-API לציין במפורש אילו מקורות מורשים לגשת למשאביו, ובכך מאפשר ליישום הרשת לתפקד כראוי.

כיצד 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: בקשת Preflight (עבור בקשות מורכבות)

עבור בקשות מורכבות יותר, כגון אלו המשתמשות במתודות HTTP כמו PUT, DELETE, או כאלה עם כותרות מותאמות אישית, הדפדפן מבצע בקשת "preflight" באמצעות מתודת HTTP OPTIONS. בקשת preflight זו מבקשת הרשאה מהשרת לפני שליחת הבקשה האמיתית. השרת משיב עם כותרות המציינות אילו מתודות, כותרות ומקורות מותרים.

בקשת Preflight של הלקוח (מ-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

הסבר על הכותרות:

אם תגובת ה-preflight של השרת מציינת שהבקשה מותרת, הדפדפן ממשיך עם הבקשה האמיתית. אחרת, הדפדפן חוסם את הבקשה.

הבקשה האמיתית של הלקוח (מ-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();

// הפעלת CORS לכל המקורות (יש להשתמש בזהירות בסביבת ייצור)
app.use(cors());

// לחלופין, הגדרת CORS למקורות ספציפיים
// 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)

# לחלופין, הגדרת CORS למקורות ספציפיים
# 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") // אפשר בקשות מ-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") // אפשר בקשות מ-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. קידוד מהנה!