Cơ chế hoạt động của chính sách CORS trên trình duyệt
Cơ chế chia sẻ tài nguyên giữa các nguồn khác nhau (CORS) là một hệ thống bảo mật được các trình duyệt web thực thi nhằm kiểm soát cách các ứng dụng web tại một nguồn gốc (origin) truy cập tài nguyên từ một nguồn gốc khác. Khi một trang web gửi yêu cầu HTTP cross-origin, trình duyệt sẽ phân tích các header trong phản hồi từ máy chủ để quyết định xem có cho phép mã nguồn JavaScript đọc dữ liệu đó hay không.
Công cụ Máy kiểm tra CORS hoạt động bằng cách mô phỏng lại các quy tắc kiểm tra nghiêm ngặt này của trình duyệt. Bằng cách phân tích các header phản hồi HTTP do bạn cung cấp cùng với các thông số chi tiết của yêu cầu (như nguồn gửi, phương thức HTTP, các header bổ sung và trạng thái thông tin xác thực), công cụ sẽ xác định chính xác liệu trình duyệt sẽ cho phép hay chặn yêu cầu đó. Quá trình xử lý này giúp các nhà phát triển front-end, back-end, vận hành hệ thống và phát triển nền tảng API nhanh chóng chẩn đoán lỗi cấu hình CORS mà không cần phải kích hoạt các yêu cầu thực tế từ ứng dụng.
Các thông số đầu vào cần thiết để kiểm tra
Để thực hiện kiểm tra chính sách CORS, bạn cần cung cấp đầy đủ các thông tin cấu hình yêu cầu và phản hồi sau:
- Phản hồi để kiểm tra: Bạn có thể chọn giữa "Phản hồi thực tế" hoặc "Phản hồi preflight". Lựa chọn này thay đổi cách công cụ áp dụng các quy tắc xác thực.
- Header phản hồi HTTP: Ô nhập văn bản chứa toàn bộ các header phản hồi từ máy chủ của bạn, tối đa là 200.000 ký tự. Đối với các phản hồi preflight, bạn cần dán kèm cả dòng trạng thái HTTP (HTTP status line). Nếu để trống, hệ thống sẽ báo lỗi: "Hãy dán các header phản hồi HTTP trước khi kiểm tra.". Nếu vượt quá giới hạn, thông báo lỗi sẽ là: "Phản hồi này dài bất thường. Hãy giữ dưới
‹max›ký tự.". Nếu định dạng dòng không đúng hoặc tên header không hợp lệ, công cụ sẽ hiển thị lỗi tương ứng: "Dòng‹line›không phải là header hoặc dòng trạng thái HTTP hợp lệ." hoặc "Dòng‹line›chứa tên header HTTP không hợp lệ.". - Nguồn của yêu cầu: Nhập chính xác giao thức (scheme), máy chủ (host) và cổng tùy chọn (port) của nguồn gửi yêu cầu, ví dụ:
https://app.example.com. Giá trị nhập vào phải là một nguồn thuần túy hoặcnull, không được chứa đường dẫn URL, truy vấn (query) hoặc thông tin xác thực. Nếu nhập sai định dạng, hệ thống sẽ báo lỗi: "Hãy nhập nguồn chỉ gồm giao thức, máy chủ và cổng tùy chọn, chẳng hạn https://app.example.com.". - Phương thức được yêu cầu: Nhập phương thức HTTP (như GET, POST, OPTIONS). Nếu token phương thức không hợp lệ, lỗi hiển thị sẽ là: "Hãy nhập token phương thức HTTP hợp lệ.". Nếu phương thức bị trình duyệt cấm sử dụng trong các yêu cầu fetch, hệ thống sẽ báo: "Các trình duyệt không cho phép phương thức
‹method›trong các yêu cầu fetch.". - Tên header yêu cầu: Nhập các tên header được gửi trong trường
Access-Control-Request-Headers, phân tách bằng dấu phẩy hoặc xuống dòng, ví dụ:Content-Type, Authorization. Nếu tên header không hợp lệ, lỗi sẽ xuất hiện: “‹header›” không phải là tên header yêu cầu HTTP hợp lệ.". - Bao gồm thông tin xác thực: Một nút chuyển đổi (toggle) để xác định xem yêu cầu có mang theo cookie hoặc thông tin xác thực HTTP (HTTP authentication) hay không.
Nếu có bất kỳ lỗi nhập liệu nào được phát hiện, hệ thống sẽ hiển thị thông báo chung: "Hãy sửa mục nhập được đánh dấu và thử lại.".
Phân tích kết quả và quyết định của trình duyệt
Sau khi phân tích các dữ liệu đầu vào, công cụ sẽ đưa ra quyết định của trình duyệt dưới các nhãn trạng thái cụ thể:
- Chưa có dữ liệu: Khi mới tải trang, trạng thái ban đầu sẽ hiển thị: "Dán phản hồi để kiểm tra chính sách CORS của nó.". Nếu bạn chưa nhập đủ thông tin mà đã nhấn kiểm tra, hệ thống sẽ báo: "Nhập chi tiết phản hồi và yêu cầu, sau đó kiểm tra chính sách CORS.".
- Được cho phép: Trạng thái "Được cho phép bởi phản hồi CORS đã dán." xuất hiện khi tất cả các quy tắc CORS được thỏa mãn.
- Bị chặn: Trạng thái "Bị chặn bởi phản hồi CORS đã dán." xuất hiện khi có ít nhất một quy tắc bị vi phạm.
- Không xác định: Trạng thái "Các header đạt yêu cầu nhưng chưa biết trạng thái preflight." hiển thị khi các header kiểm tra đều hợp lệ nhưng thiếu thông tin trạng thái của phản hồi preflight.
Bên cạnh quyết định chung, công cụ hiển thị mục "Các trường Access-Control đã phân tích" để liệt kê chi tiết các trường Access-Control-* tìm thấy trong phản hồi. Nếu một trường không tồn tại, nó sẽ được đánh dấu là "Không có".
Các quy tắc kiểm tra CORS và trường hợp đặc biệt
Quy trình kiểm tra của trình duyệt tuân thủ nghiêm ngặt các quy tắc kỹ thuật sau đây, đặc biệt là khi xử lý thông tin xác thực và các ký tự đại diện:
Quy tắc về nguồn gốc và thông tin xác thực
- Khớp nguồn gốc: Trình duyệt sẽ kiểm tra xem
Access-Control-Allow-Origincó khớp chính xác với nguồn của yêu cầu hay không. Khi khớp, lý do hiển thị là: "Access-Control-Allow-Origin khớp chính xác với‹origin›.". Nếu không khớp, lý do sẽ là: "Access-Control-Allow-Origin là‹actual›, không phải‹expected›.". - Sử dụng ký tự đại diện: Ký tự đại diện
*cho phép mọi nguồn gốc truy cập ("Access-Control-Allow-Origin cho phép mọi nguồn gốc cho yêu cầu này."). Tuy nhiên, nếu yêu cầu bao gồm thông tin xác thực,Access-Control-Allow-Originkhông được phép sử dụng ký tự*. Nếu vi phạm, trình duyệt sẽ chặn với lý do: "Access-Control-Allow-Origin không thể * khi bao gồm thông tin xác thực.". - Yêu cầu xác thực: Khi yêu cầu bao gồm thông tin xác thực, header
Access-Control-Allow-Credentialsbắt buộc phải có mặt và có giá trị chính xác làtrue. Nếu hợp lệ, hệ thống ghi nhận: "Access-Control-Allow-Credentials chính xác là true.". Nếu thiếu, yêu cầu bị chặn với lý do: "Yêu cầu có thông tin xác thực cần Access-Control-Allow-Credentials: true.". Ngược lại, nếu yêu cầu không chứa thông tin xác thực, sự hiện diện của header này không ảnh hưởng đến quyết định ("Thông tin xác thực không được bao gồm nên Access-Control-Allow-Credentials không ảnh hưởng đến quyết định này."). - Giá trị không hợp lệ: Nếu
Access-Control-Allow-Originchứa nhiều giá trị hoặc được phân tách bằng dấu phẩy, giá trị đó bị coi là không hợp lệ ("Access-Control-Allow-Origin có giá trị không hợp lệ:‹value›.") hoặc nếu thiếu hoàn toàn thì lý do sẽ là: "Access-Control-Allow-Origin bị thiếu.".
Quy tắc đối với phương thức và header trong yêu cầu Preflight
Yêu cầu preflight (sử dụng phương thức OPTIONS) được trình duyệt gửi đi trước để kiểm tra xem máy chủ có chấp thuận phương thức và các header tùy chỉnh của yêu cầu thực tế hay không.
- Trạng thái phản hồi preflight: Phản hồi preflight bắt buộc phải trả về trạng thái thành công thuộc nhóm 2xx. Nếu thành công, lý do là: "Trạng thái preflight
‹status›thành công.". Nếu trạng thái không thuộc nhóm 2xx, yêu cầu bị chặn: "Trạng thái preflight‹status›không phải là trạng thái 2xx thành công.". Nếu bạn không dán dòng trạng thái HTTP trong phản hồi preflight, hệ thống sẽ báo: "Không có dòng trạng thái HTTP nên không thể kiểm tra trạng thái preflight 2xx bắt buộc.". - Kiểm tra phương thức: Phương thức yêu cầu phải được cho phép bởi header
Access-Control-Allow-Methods("Preflight cho phép‹method›."). Nếu phương thức nằm trong danh sách an toàn của CORS (CORS-safelisted), nó không cần phải khai báo trong header này ("‹method›là phương thức nằm trong danh sách an toàn của CORS và không cần xuất hiện trong Access-Control-Allow-Methods."). Nếu không được phép, lý do chặn là: "Access-Control-Allow-Methods không cho phép‹method›.". - Kiểm tra header: Các header yêu cầu phải được chấp thuận bởi
Access-Control-Allow-Headers("Preflight cho phép các tên header yêu cầu:‹headers›."). Nếu không có header nào cần phê duyệt preflight, hệ thống ghi nhận: "Không có tên header yêu cầu nào cần được preflight chấp thuận.". - Ảnh hưởng của thông tin xác thực lên ký tự đại diện: Nếu yêu cầu không bao gồm thông tin xác thực, ký tự đại diện
*trongAccess-Control-Allow-Headerssẽ bao gồm tất cả các header được yêu cầu ("Access-Control-Allow-Headers: * bao gồm các tên này cho yêu cầu không có thông tin xác thực:‹headers›."). Tuy nhiên, nếu yêu cầu có thông tin xác thực, các ký tự đại diện cho phương thức và header sẽ mất đi ý nghĩa đại diện rộng rãi của chúng và phải được liệt kê chính xác. - Trường hợp đặc biệt của Authorization: Header
Authorizationlà một ngoại lệ bắt buộc. Ngay cả khi cấu hìnhAccess-Control-Allow-Headers: *đang được sử dụng, headerAuthorizationvẫn phải được liệt kê một cách rõ ràng trong danh sách cho phép. Nếu không, yêu cầu sẽ bị chặn với lý do: "Authorization phải được liệt kê rõ ràng; Access-Control-Allow-Headers: * không bao gồm header này.". Nếu các header khác không được phép, lý do sẽ là: "Access-Control-Allow-Headers không cho phép:‹headers›.".
Quyền riêng tư và giới hạn kỹ thuật
Khi sử dụng Máy kiểm tra CORS, toàn bộ dữ liệu về các header phản hồi và chi tiết yêu cầu của bạn chỉ được xử lý trực tiếp bên trong trình duyệt web của bạn. BroBroGo không tải lên hoặc lưu trữ bất kỳ nội dung nào bạn nhập vào hệ thống.
Tuy nhiên, người dùng cần lưu ý các giới hạn kỹ thuật sau khi đánh giá kết quả:
- Công cụ chỉ thực hiện phân tích tĩnh dựa trên các header phản hồi và chi tiết yêu cầu do bạn dán vào. Công cụ không thực hiện liên hệ với máy chủ thực tế, không đọc nội dung từ các URL, không thiết lập cookie, không kiểm tra cấu hình DNS/TLS và không thể sửa đổi cấu hình máy chủ của bạn.
- Một kết quả kiểm tra đạt (Allowed) trên công cụ chỉ xác nhận rằng các dữ liệu bạn đã dán là hợp lệ theo đặc tả CORS. Kết quả này không thể đảm bảo rằng yêu cầu thực tế trên môi trường production sẽ hoạt động hoàn hảo, vì nó không thể tính đến các yếu tố ngoại cảnh như lệnh chuyển hướng (redirects), phản hồi được lưu trong bộ nhớ đệm (cache), các quy tắc máy chủ thay đổi liên tục, sự can thiệp của các tiện ích mở rộng trên trình duyệt (browser extensions), hoặc nội dung của phản hồi thực tế nhận được sau khi preflight thành công.
Câu hỏi thường gặp (FAQ)
Tôi nên dán phản hồi thực tế hay phản hồi preflight? Dùng phản hồi thực tế để kiểm tra xem mã chạy trong trình duyệt có đọc được phản hồi hay không. Dùng phản hồi preflight để kiểm tra xem phản hồi OPTIONS có chấp thuận phương thức và các tên header của yêu cầu tiếp theo hay không.
Tại sao ký tự đại diện có thể không thành công với thông tin xác thực? Khi có cookie hoặc xác thực HTTP, nguồn được phép phải khớp chính xác với nguồn của yêu cầu. Ký tự đại diện cho phương thức và header được phép cũng không còn mang nghĩa “mọi giá trị”.
Kết quả đạt có chứng minh được yêu cầu trực tiếp sẽ hoạt động không? Không. Kết quả chỉ áp dụng cho phản hồi đã dán và chi tiết yêu cầu nhập tại đây. Lệnh chuyển hướng, phản hồi trong bộ nhớ đệm, thay đổi quy tắc máy chủ, tiện ích trình duyệt và phản hồi thực tế sau preflight vẫn có thể làm thay đổi kết quả.
*Tại sao header Authorization của tôi bị chặn dù đã cấu hình Access-Control-Allow-Headers là ?
Header Authorization là một trường hợp đặc biệt trong đặc tả CORS. Trình duyệt yêu cầu header này phải được liệt kê một cách rõ ràng và chi tiết trong Access-Control-Allow-Headers, ký tự đại diện * không có hiệu lực bao phủ đối với riêng header này.