Plugin CORS
Plugin Cors (tên kỹ thuật cors, nhóm Security) gắn các header CORS chuẩn (Access-Control-Allow-Origin, Access-Control-Allow-Methods…) vào response, để trình duyệt biết trang web ở origin khác có được đọc response hay không.
CORS không phải cơ chế bảo mật phía server. Header CORS chỉ là chỉ dẫn cho trình duyệt. Request gửi bằng curl, Postman hay từ server khác bỏ qua CORS và vẫn tới được backend. Muốn kiểm soát ai được gọi API, dùng thêm plugin xác thực như JWT Auth hoặc OpenID Connect.
Trường hợp sử dụng
Plugin CORS phù hợp khi ứng dụng frontend (SPA, mobile web) chạy trên domain khác với domain của API Gateway và gọi API bằng JavaScript (fetch / XHR). Khi thiếu header CORS, trình duyệt chặn JavaScript đọc response, dù request vẫn tới và được backend xử lý.
Các trường hợp điển hình:
- Frontend tại
https://app.example.comgọi API tạihttps://api.example.com: khai báohttps://app.example.comtrongallow_origins. - Nhiều tenant dùng subdomain động dạng
*.customer.example.comcùng gọi một API: dùngallow_origins_by_regexthay vì liệt kê từng domain. - Nhiều Route / Service dùng chung một danh sách origin: dùng
allow_origins_by_metadatađể khai báo tập trung một lần. - Request gửi kèm cookie hoặc header
Authorization: bậtallow_credentialvà khai báo cụ thể origin, method, header (không dùng*). - Backend trả về header tùy biến (ví dụ
X-Request-Id) mà JavaScript phía client cần đọc: khai báo header đó trongexpose_headers.
Tạo plugin CORS
Để tạo plugin CORS, bạn thực hiện các bước sau:
-
Chọn API Gateway → Plugin ở menu bên trái, chọn API Gateway ở góc trên bên phải, nhấn New plugin, rồi chọn Cors (nhóm Security) trong popup Add plugin. Bạn cũng có thể thêm từ tab Plugins của Route / Service, xem Thêm Plugin.
-
Nhập Display Name tại mục Basic Information. Xem Basic Information.
-
Chọn mục Configuration. Form hiển thị sẵn đủ 10 thuộc tính của plugin, panel Manage Attribute không còn thuộc tính nào để thêm.

| Attribute | Bắt buộc | Mô tả |
|---|---|---|
| allow_origins | Y | Các origin được gọi cross-origin, dạng scheme://host:port (ví dụ https://app.example.com), nhiều origin cách nhau bằng dấu phẩy. * cho phép mọi origin, chỉ dùng được khi không bật allow_credential. Mặc định *. |
| allow_origins_by_metadata | N | Tham chiếu tới danh sách origin đã định nghĩa trong Plugin metadata, thay vì gõ lại ở từng plugin. Dùng khi nhiều Route / Service chung một danh sách origin. Nhấn + Add để thêm từng dòng. |
| allow_origins_by_regex | N | Các biểu thức chính quy khớp origin được phép, ví dụ .*\.test\.com$. Dùng khi có quá nhiều domain hoặc domain sinh động theo tenant. Khi đã khai, chỉ origin khớp regex được chấp nhận, bất kể allow_origins. |
| allow_methods | Y | Các HTTP method được bật CORS, tích chọn trong: *, **, GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, PATCH. Chọn * (hoặc **) sẽ tự bỏ chọn các method cụ thể. Mặc định *. |
| allow_headers | N | Các header client được gửi kèm trong request cross-origin, ví dụ Authorization,Content-Type, cách nhau bằng dấu phẩy. * cho phép tất cả, không dùng được khi bật allow_credential. Mặc định *. |
| expose_headers | N | Các header của response mà JavaScript phía client được đọc, ví dụ X-Request-Id. Để trống thì plugin không can thiệp header Access-Control-Expose-Headers. |
| max_age | N | Thời gian (giây) trình duyệt cache kết quả preflight OPTIONS, đặt lớn hơn để giảm số request preflight. -1 là không cache. Chỉ nhận số nguyên từ -1 trở lên. Mặc định 5. |
| allow_credential | N | Cho phép request mang credential (cookie, header Authorization). Bật lên thì không được để * ở allow_origins, allow_methods, allow_headers. Mặc định tắt. |
| timing_allow_origins | N | Các origin được đọc thông tin đo hiệu năng tải tài nguyên (header Timing-Allow-Origin). Chỉ liên quan tới Resource Timing API, không ảnh hưởng việc gọi API. |
| timing_allow_origins_by_regex | N | Như timing_allow_origins nhưng khai bằng regex. |
Khi bật allow_credential, cả 3 field allow_origins, allow_methods, allow_headers đang để * đều hiện cảnh báo You cannot use '*' here while allow_credential is enabled. Cảnh báo không chặn nút Create, nhưng cấu hình đó không hoạt động đúng trên trình duyệt. Hãy khai rõ origin, method, header cần cho phép thay cho *.
Giá trị ** ép bật * bất chấp quy tắc trên. Đây là rủi ro bảo mật (mở đường cho tấn công CSRF), không dùng ở môi trường production.

-
Chọn mục Scope. Nếu mọi API phục vụ chung một nhóm frontend, chọn Global cho gọn. Nếu mỗi nhóm API có danh sách origin khác nhau, tạo nhiều plugin CORS Scoped theo từng Route / Service. Xem Scope.
-
Nhấn Create. Thông báo Plugin created successfully hiển thị và plugin xuất hiện trong danh sách.
Cấu hình mẫu
Cấu hình mặc định, mở cho mọi origin. Chạy được ngay nhưng không nên giữ khi lên production:
{
"allow_origins": "*",
"allow_methods": "*",
"allow_headers": "*",
"expose_headers": "",
"max_age": 5,
"allow_credential": false
}
SPA ở https://app.example.com gọi API có kèm header Authorization. Khai rõ từng giá trị thay cho * (vì bật allow_credential), giữ OPTIONS trong allow_methods để request preflight đi qua, và đặt max_age lớn để trình duyệt ít phải preflight lại:
{
"allow_origins": "https://app.example.com",
"allow_methods": "GET,POST,OPTIONS",
"allow_headers": "Authorization,Content-Type",
"expose_headers": "X-Request-Id",
"max_age": 3600,
"allow_credential": true
}
Nhiều tenant dùng subdomain động (https://acme.customer.example.com, https://beta.customer.example.com…), dùng allow_origins_by_regex:
{
"allow_origins": "https://app.customer.example.com",
"allow_origins_by_regex": [
"^https://[a-z0-9-]+\\.customer\\.example\\.com$"
],
"allow_methods": "GET,POST,PUT,DELETE,OPTIONS",
"allow_headers": "Authorization,Content-Type",
"max_age": 3600,
"allow_credential": true
}
- Khi đã khai
allow_origins_by_regex, chỉ origin khớp regex được chấp nhận.allow_originsvẫn là field bắt buộc nên vẫn phải có giá trị: điền một origin cụ thể, không để*khi đang bậtallow_credential. - Neo hai đầu regex bằng
^và$, và escape dấu chấm (\.). Nếu không,.khớp mọi ký tự và domain nhưhttps://evil-customerXexample.comcũng lọt qua.
Kiểm tra hoạt động
Sau khi tạo plugin, bạn gửi thử request để xem API Gateway có gắn header CORS vào response theo đúng cấu hình không. Ví dụ dưới đây dùng plugin cors với cấu hình:
{
"max_age": 5,
"allow_headers": "Test_content",
"allow_methods": "*",
"allow_origins": "*",
"allow_credential": false
}
Để kiểm tra plugin CORS, bạn thực hiện các bước sau:
- Mở màn hình chi tiết plugin, mục Configuration, để xem cấu hình đang áp dụng. Xem Xem thông tin Plugin.

-
Gửi request tới Gateway URL kèm path của một Route nằm trong Scope của plugin, ví dụ
POST https://YOUR_GATEWAY_URL/v2/pet. Cách lấy Gateway URL và gửi request, xem Kiểm tra Route. -
Mở tab Headers của response và đối chiếu với cấu hình:
| Attribute | Giá trị cấu hình | Header trong response |
|---|---|---|
allow_origins | * | Access-Control-Allow-Origin: * |
allow_methods | * | Access-Control-Allow-Methods: * |
allow_headers | Test_content | Access-Control-Allow-Headers: Test_content |
max_age | 5 | Access-Control-Max-Age: 5 |
allow_credential | false | Không có header Access-Control-Allow-Credentials |

Response có đủ các header Access-Control-* như bảng trên nghĩa là plugin đang hoạt động. Nếu không thấy các header này, kiểm tra request có đi qua Route / Service trong Scope của plugin không, và plugin có đang bật không, xem Bật / Tắt Plugin.
Lỗi thường gặp
| Lỗi | Nguyên nhân | Cách xử lý |
|---|---|---|
| You cannot use '*' here while allow_credential is enabled. | Bật allow_credential nhưng allow_origins / allow_methods / allow_headers vẫn để * | Khai rõ origin, method, header thay cho *. |
| Invalid regular expression. | allow_origins_by_regex sai cú pháp regex | Sửa lại biểu thức chính quy. |
| Enter a whole number greater than or equal to -1. | max_age không phải số nguyên, hoặc nhỏ hơn -1 | Nhập số nguyên từ -1 trở lên. |