Khái niệm về CORS và Chính sách đồng nguồn (Same-Origin Policy)
Trong phát triển web, Same-Origin Policy (SOP) là một cơ chế bảo mật quan trọng của trình duyệt. Nó ngăn chặn các tập lệnh từ một nguồn (origin) này tương tác với tài nguyên từ một nguồn khác. Một "nguồn" được xác định bởi bộ ba (tuple): Giao thức (Protocol), Tên miền (Domain), và Cổng (Port). Nếu một trong ba yếu tố này khác biệt, trình duyệt sẽ coi đó là một yêu cầu khác nguồn (Cross-Origin).
Dưới đây là bảng so sánh tính đồng nguồn so với URL gốc http://example.com/data/index.html:
| URL Kiểm tra | Kết quả | Lý do |
|---|---|---|
http://example.com/data/config.json |
Thành công | Cùng giao thức, tên miền và cổng |
https://example.com/data/index.html |
Thất bại | Khác giao thức (HTTP vs HTTPS) |
http://example.com:8080/data/index.html |
Thất bại | Khác cổng (Mặc định 80 vs 8080) |
http://api.example.com/data/index.html |
Thất bại | Khác tên miền (Subdomain khác nhau) |
Giải quyết vấn đề CORS trong Django
Để cho phép các ứng dụng phía Client (như React, Vue hoặc Mobile App) truy cập vào API của Django từ một nguồn khác, chúng ta cần thêm các Header CORS vào phản hồi HTTP. Cách linh hoạt nhất là tạo một Middleware tùy chỉnh.
1. Tạo Middleware xử lý Header
Bạn hãy tạo một file mới có tên cors_middleware.py trong ứng dụng của mình (ví dụ thư mục utils/ hoặc ngay trong thư mục app chính):
class CustomCORSHandler:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# Thực thi xử lý request trước khi chuyển đến View
response = self.get_response(request)
# Thêm các header cần thiết để cho phép truy cập liên nguồn
response["Access-Control-Allow-Origin"] = "*" # Cho phép tất cả các nguồn
# Cấu hình các phương thức HTTP được phép
response["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
# Cấu hình các Header được phép gửi từ Client
response["Access-Control-Allow-Headers"] = "Content-Type, Authorization, X-Requested-With"
return response
2. Đăng ký Middleware vào hệ thống
Sau khi đã định nghĩa Middleware, bạn cần khai báo nó trong file cấu hình settings.py của dự án Django để nó có hiệu lực toàn cục.
# settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
# Thêm Middleware tùy chỉnh của bạn vào đây
'your_app_name.utils.cors_middleware.CustomCORSHandler',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Lưu ý về bảo mật
Trong ví dụ trên, việc thiết lập Access-Control-Allow-Origin: "*" sẽ cho phép bất kỳ trang web nào cũng có thể gửi yêu cầu đến server của bạn. Trong môi trường sản xuất (Production), bạn nên thay thế dấu * bằng tên miền cụ thể của ứng dụng Frontend để đảm bảo an toàn dữ liệu.
Ngoài ra, đối với các yêu cầu phức tạp (như sử dụng JWT hoặc Cookies), bạn có thể cần thêm header Access-Control-Allow-Credentials và xử lý các yêu cầu OPTIONS (Preflight request) một cách chi tiết hơn.