Việt Nam có cộng đồng lập trình viên Laravel/PHP rất lớn, và framework này đi kèm file config/cors.php sẵn từ phiên bản 7. Một tình huống phổ biến: trong lúc phát triển với Vite dev server chạy ở cổng khác với API Laravel, lập trình viên đặt 'allowed_origins' => ['*'] để tránh lỗi CORS gây khó chịu, rồi quên siết lại trước khi triển khai. Nó vẫn chạy êm cho các request GET đơn giản, cho tới khi bật 'supports_credentials' => true để dùng Sanctum xác thực qua cookie — lúc đó trình duyệt bắt đầu từ chối vì origin wildcard không được phép đi kèm credentials.
Chính sách cùng nguồn gốc
Theo mặc định, trình duyệt thực thi Same-Origin Policy: code JavaScript trên một trang từ một nguồn gốc (domain + scheme + port) không thể đọc response từ các request được gửi đến một nguồn gốc khác. Đây là một cơ chế bảo mật căn bản ngăn một script độc hại trên một trang web đánh cắp dữ liệu từ trang web khác nơi người dùng đang đăng nhập.
CORS nới lỏng chính sách này như thế nào
CORS (Cross-Origin Resource Sharing) là một tập hợp các header HTTP mà server dùng để chủ động cho phép các nguồn gốc bên ngoài nhất định (hoặc tất cả) đọc response của nó. Header quan trọng nhất là Access-Control-Allow-Origin, cho biết domain nào được cấp phép.
Cái bẫy wildcard kết hợp credentials
Khi một request được gửi kèm credentials: 'include' — cần thiết để gửi cookie phiên đến một API trên subdomain khác — trình duyệt hoàn toàn từ chối chấp nhận Access-Control-Allow-Origin: * trong response. Đặc tả cấm rõ ràng việc kết hợp origin wildcard với credentials; server bắt buộc phải trả về đúng origin đã gửi request.
Vì sao cần điều này
- Chẩn đoán lỗi CORS và tìm hiểu chính xác header nào đang thiếu trên server.
- Phát hiện cấu hình
config/cors.phpcủa Laravel còn quá lỏng lẻo trước khi lên production. - Hiểu sự khác biệt giữa request "đơn giản" và request preflight (OPTIONS).
CORS không bảo vệ server khỏi các cuộc tấn công
Một hiểu lầm phổ biến là nghĩ rằng CORS là biện pháp bảo mật phía server — thực ra nó chỉ giới hạn những gì JavaScript trong trình duyệt có thể đọc được. Kẻ tấn công dùng curl, Postman, hoặc một script backend trực tiếp sẽ hoàn toàn bỏ qua CORS, vì các công cụ đó không thực thi chính sách cùng nguồn gốc. CORS không bao giờ nên được coi là thay thế cho việc xác thực và ủy quyền thực sự trên server.