Chuyển tới nội dung chính

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.

cảnh báo

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.com gọi API tại https://api.example.com: khai báo https://app.example.com trong allow_origins.
  • Nhiều tenant dùng subdomain động dạng *.customer.example.com cùng gọi một API: dùng allow_origins_by_regex thay 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ật allow_credential và 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 đó trong expose_headers.

Tạo plugin CORS​

Để tạo plugin CORS, bạn thực hiện các bước sau:

  1. 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.

  2. Nhập Display Name tại mục Basic Information. Xem Basic Information.

  3. 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.

Mục Configuration của plugin CORS với giá trị mặc định

AttributeBắt buộcMô tả
allow_originsYCá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_metadataNTham 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_regexNCá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_methodsYCá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_headersNCá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_headersNCá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_ageNThờ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_credentialNCho 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_originsNCá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_regexNNhư timing_allow_origins nhưng khai bằng regex.
cảnh báo

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.

Cảnh báo khi bật allow_credential mà vẫn để dấu sao

  1. 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.

  2. 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
}
mẹo
  • Khi đã khai allow_origins_by_regex, chỉ origin khớp regex được chấp nhận. allow_origins vẫ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ật allow_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.com cũ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:

  1. 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.

Mục Configuration của plugin cors với allow_origins, allow_methods, allow_headers, max_age

  1. 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.

  2. Mở tab Headers của response và đối chiếu với cấu hình:

AttributeGiá trị cấu hìnhHeader trong response
allow_origins*Access-Control-Allow-Origin: *
allow_methods*Access-Control-Allow-Methods: *
allow_headersTest_contentAccess-Control-Allow-Headers: Test_content
max_age5Access-Control-Max-Age: 5
allow_credentialfalseKhông có header Access-Control-Allow-Credentials

Response 200 OK với các header Access-Control-* do plugin CORS gắn vào

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ỗiNguyên nhânCá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 regexSử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 -1Nhập số nguyên từ -1 trở lên.

Bước tiếp theo​

Cập nhật lần cuối vào