Hãy xem xét ví dụ sau đây:
Dưới đây là 1 web ở địa chỉ http://localhost:6003
đang gọi 1 request sang https://www.section.io
và vi phạm CORS policy.
Nội dung bài viết
I. Định nghĩa
Nói đơn giản: CORS (cross-origin resource sharing) là việc chặn dùng script ở site A lấy data ở site B nếu site A và B không chung origin.
Thế nào là 2 sites có cùng origin? Đó là 2 site mà có chung {scheme, host, port}
,
ví dụ link sau: http://www.example.com/dir/page.html
có
- scheme: http
- host: www.example.com
- port: 80
http://www.example.com/dir2/other.html | Success | Same scheme, host and port |
http://www.example.com/dir/page2.html | Success | Same scheme, host and port |
http://www.example.com:80/dir/other.html | Success | Most modern browsers implicitly assign the protocol’s default port when omitted. |
http://username:password@www.example.com/dir2/other.html | Success | Same scheme, host and port |
https://www.example.com/dir/other.html | Failure | Different scheme |
http://www.example.com:81/dir/other.html | Failure | Same scheme and host but different port |
http://v2.www.example.com/dir/other.html | Failure | Different host (exact match required) |
http://example.com/dir/other.html | Failure | Different host (exact match required) |
http://en.example.com/dir/other.html | Failure | Different host |
Browset chỉ cho phép bạn get file Javascript và CSS từ 1 địa chỉ khác, chứ ko cho phép bạn load data.
II. Nếu không có CORS thì sao?
- Giả sử bạn đang login Gmail ở browser, Gmail sẽ sử dụng cookie để lưu giữ session đăng nhập của bạn.
- Ai đó gửi cho bạn 1 cái link, bạn vô tình bấm vào và nó mở 1 trang web khác. Trang web đó có 1 đoạn script access vào cookie của browser và lấy session đăng nhập Gmail trên rồi giả là chính bạn đang sử dụng API của Gmail gọi vào Gmail API để lấy thông tin.
- Nếu Gmail không dùng CORS policy thì đoạn script đó chắc chắn sẽ lấy được thông tin.
Tất nhiên là ở step số 2, hiện tại có các biện pháp khác để ko cho phép script access vào cookie của browser, tuy nhiên, có thêm biện pháp bảo vệ nữa thì vẫn tốt hơn.
III. Làm thế nào để lách qua CORS?
Trên thực tế, việc phải load data từ 1 site khác là việc thường gặp và phải có cách để nới lỏng cái policy này. Trước tiên thì phải hiểu cơ chế hoạt động của CORS policy đã. Nó dựa vào preflight request để hỏi trước là domain này có được phép get data không và những method mà server support là gì.
Preflighted request sẽ có cấu trúc nhu·
Method
: OPTIONSPath
: url path của nơi chứa dataOrigin
:{scheme, host, port}
của nơi gửi requestAccess-Control-Request-Method
: method của request mà nó muốn gửi, trong ví dụ là nó muốn gửi method POST đến/doc
Access-Control-Request-Headers
: những header khác mà nó muốn gửi thêm
Server nhận được request OPTIONS này và sẽ trả lại response:
Access-Control-Allow-Origin: https://foo.example
: server chỉ chấp nhận orignhttps://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
:\doc
chấp nhận 3 methods khác nhauAccess-Control-Allow-Headers: X-PINGOTHER, Content-Type
: list nhưng header mà server chấp nhận.
Và khi vi phạm 1 trong những lỗi trên thì browser sẽ chặn request lại và báo lỗi CORS.
- Sai origin
- Dùng method khác những method được chấp nhận
- Hoặc dùng header nằm ngoài những header mà server chấp nhận
Trong trường hợp test, để khỏi phiền phức, dev có thể sẽ config như sau để server chấp nhận mọi origin, có nghĩa là request từ đâu đến cũng ok hết. (chỉ dùng khi đang development thôi nha, lên production là ko được đâu)
Access-Control-Allow-Origin:
*
IV. Tổng kết
CORS là 1 trong những cơ chế để duyệt web an toàn hơn, biết thêm nó sẽ giúp bạn thêm kiến thức mảng web security và không bất ngờ khi gặp lỗi này trong lúc test. Hi vọng bài có ích cho bạn nào cần. 😀