Bạn đang xem tài liệu về Apigee Edge.
Chuyển đến
Tài liệu về Apigee X. thông tin
CORS (Chia sẻ tài nguyên trên nhiều nguồn gốc) là một cơ chế chuẩn cho phép JavaScript Các lệnh gọi XMLHttpRequest (XHR) được thực thi trên một trang web để tương tác với các tài nguyên không có nguồn gốc miền. CORS là một giải pháp thường được triển khai cho "same-origin chính sách" được thực thi bởi tất cả trình duyệt. Ví dụ: nếu bạn thực hiện lệnh gọi XHR đến API Twitter từ mã JavaScript thực thi trong trình duyệt của mình thì lệnh gọi sẽ không thành công. Điều này là do miền phân phối trang đến trình duyệt của bạn không giống với miền phân phối API Twitter. CORS cung cấp giải pháp cho sự cố này bằng cách cho phép máy chủ "chọn tham gia" nếu họ muốn cung cấp tài nguyên trên nhiều nguồn gốc chia sẻ.
Video: Xem video ngắn để tìm hiểu cách bật CORS trên proxy API.
Trường hợp sử dụng điển hình cho CORS
Mã JQuery sau đây gọi một dịch vụ mục tiêu giả định. Nếu được thực thi từ bên trong ngữ cảnh của một trình duyệt (trang web), lệnh gọi sẽ không thành công do chính sách cùng nguồn gốc:
<script> var url = "http://service.example.com"; $(document).ready(function(){ $("button").click(function(){ $.ajax({ type:"GET", url:url, async:true, dataType: "json", success: function(json) { // Parse the response. // Do other things. }, error: function(xhr, status, err) { // This is where we end up! } }); }); }); </script>
Một giải pháp cho vấn đề này là tạo proxy API Apigee gọi API dịch vụ trên phần phụ trợ. Hãy nhớ rằng Edge nằm giữa ứng dụng (trong trường hợp này là trình duyệt) và phần phụ trợ API (dịch vụ). Do proxy API thực thi trên máy chủ, không phải trong trình duyệt, nên proxy có thể gọi dịch vụ thành công. Sau đó, bạn chỉ cần là đính kèm tiêu đề CORS vào phản hồi TargetEndpoint. Miễn là trình duyệt hỗ trợ CORS, các tiêu đề này báo hiệu cho trình duyệt rằng bạn có thể "thư giãn" của chính sách cùng nguồn gốc, cho phép lệnh gọi API trên nhiều nguồn gốc để thành công.
Sau khi tạo proxy có hỗ trợ CORS, bạn có thể gọi URL proxy API thay vì trong mã phía máy khách của bạn. Ví dụ:
<script> var url = "http://myorg-test.apigee.net/v1/example"; $(document).ready(function(){ $("button").click(function(){ $.ajax({ type:"GET", url:url, async:true, dataType: "json", success: function(json) { // Parse the response. // Do other things. }, error: function(xhr, status, err) { // This time, we do not end up here! } }); }); }); </script>
Đính kèm chính sách Thêm CORS vào API mới proxy
Bạn có thể thêm tính năng hỗ trợ CORS vào proxy API bằng cách đính kèm "Add CORS" (Thêm CORS) chính sách đối với proxy API khi tạo chiến dịch. Để thêm chính sách này, hãy chọn hộp đánh dấu Thêm tiêu đề CORS (Chia sẻ tài nguyên giữa nhiều nguồn gốc) trong trang Bảo mật trong trình hướng dẫn Tạo proxy.
Khi bạn đánh dấu vào hộp này, một chính sách có tên là Add CORS (Thêm CORS) sẽ tự động được thêm vào hệ thống và được đính kèm vào luồng phản hồi TargetEndpoint trước đó, như minh hoạ trong hình sau:
Chính sách Thêm CORS được triển khai dưới dạng AssignmentMessage (chính sách gán), tức là sẽ thêm tiêu đề thích hợp vào phản hồi. Về cơ bản, các tiêu đề cho trình duyệt biết trình duyệt sẽ chia sẻ tài nguyên của mình với nguồn gốc nào, phương thức nào mà hàm đó chấp nhận, v.v. Bạn có thể đọc thêm về các tiêu đề CORS này trong Đề xuất về việc chia sẻ tài nguyên trên nhiều nguồn gốc W3C.
Bạn nên sửa đổi chính sách như sau:
- Thêm các tiêu đề
content-type
vàauthorization
(bắt buộc để hỗ trợ xác thực cơ bản hoặc OAuth2) vào tiêu đềAccess-Control-Allow-Headers
, như minh hoạ trong phần trích dẫn mã dưới đây. - Đối với việc xác thực OAuth2, bạn có thể cần thực hiện các bước để khắc phục hành vi không tuân thủ RFC.
- Bạn nên sử dụng
<Set>
để đặt tiêu đề CORS thay vì<Add>
, như minh hoạ trong phần trích dẫn bên dưới. Khi sử dụng<Add>
, nếu tiêu đềAccess-Control-Allow-Origin
đã tồn tại thì bạn sẽ gặp lỗi sau:The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.
Để biết thêm thông tin, hãy xem Lỗi CORS : tiêu đề chứa nhiều giá trị '*, *', nhưng chỉ cho phép một giá trị.
<AssignMessage async="false" continueOnError="false" enabled="true" name="add-cors"> <DisplayName>Add CORS</DisplayName> <FaultRules/> <Properties/> <Set> <Headers> <Header name="Access-Control-Allow-Origin">{request.header.origin}</Header> <Header name="Access-Control-Allow-Headers">origin, x-requested-with, accept, content-type, authorization</Header> <Header name="Access-Control-Max-Age">3628800</Header> <Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header> </Headers> </Set> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <AssignTo createNew="false" transport="http" type="response"/> </AssignMessage>
Thêm tiêu đề CORS vào proxy hiện có
Bạn cần tạo chính sách Chỉ định tin nhắn mới theo cách thủ công rồi sao chép mã cho cơ chế Thêm CORS chính sách được liệt kê ở phần trước vào đó. Sau đó, đính kèm chính sách này vào luồng trước phản hồi của TargetEndpoint của proxy API. Bạn có thể sửa đổi các giá trị tiêu đề nếu cần. Để biết thêm thông tin về cách tạo và đính kèm chính sách, hãy xem phần Chính sách là gì?.
Xử lý CORS yêu cầu kiểm tra
Quá trình kiểm tra CORS (Chia sẻ tài nguyên giữa nhiều nguồn gốc) đề cập đến việc gửi một yêu cầu đến máy chủ để xác minh xem yêu cầu đó hỗ trợ CORS. Phản hồi điển hình của quy trình kiểm tra bao gồm những nguồn gốc mà máy chủ sẽ chấp nhận CORS từ yêu cầu, danh sách các phương thức HTTP được hỗ trợ cho các yêu cầu CORS, tiêu đề có thể được được dùng trong yêu cầu tài nguyên, thời gian tối đa của phản hồi kiểm tra sẽ được lưu vào bộ nhớ đệm và khác. Nếu dịch vụ không hỗ trợ CORS hoặc không muốn chấp nhận yêu cầu trên nhiều nguồn gốc các yêu cầu từ máy khách gốc của ứng dụng, thì chính sách về nhiều nguồn gốc của trình duyệt sẽ được thực thi và mọi yêu cầu trên nhiều miền được thực hiện từ máy khách để tương tác với các tài nguyên được lưu trữ trên máy chủ đó sẽ không thành công.
Thông thường, các yêu cầu kiểm tra CORS được thực hiện bằng phương thức HTTP OPTIONS. Khi một máy chủ hỗ trợ CORS nhận yêu cầu OPTIONS, sẽ trả về một tập hợp các tiêu đề CORS cho ứng dụng khách cho biết mức độ hỗ trợ CORS. Nhờ có cái bắt tay này, khách hàng biết được điều đó được phép yêu cầu từ miền không phải nguồn gốc.
Để biết thêm thông tin về quy trình kiểm tra, hãy tham khảo bài viết Đề xuất về việc chia sẻ tài nguyên trên nhiều nguồn gốc W3C. Có trong ngoài ra còn có nhiều blog và bài viết về CORS mà bạn có thể tham khảo.
Apigee không có giải pháp kiểm tra CORS ngay từ đầu, nhưng có thể như được mô tả trong phần này. Mục tiêu là để proxy đánh giá OPTIONS yêu cầu trong luồng có điều kiện. Sau đó, proxy có thể gửi lại phản hồi thích hợp cho khách hàng.
Hãy cùng xem một quy trình mẫu, sau đó thảo luận về các phần xử lý yêu cầu kiểm tra:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ProxyEndpoint name="default"> <Description/> <Flows> <Flow name="OptionsPreFlight"> <Request/> <Response> <Step> <Name>add-cors</Name> </Step> </Response> <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition> </Flow> </Flows> <PreFlow name="PreFlow"> <Request/> <Response/> </PreFlow> <HTTPProxyConnection> <BasePath>/v1/cnc</BasePath> <VirtualHost>default</VirtualHost> <VirtualHost>secure</VirtualHost> </HTTPProxyConnection> <RouteRule name="NoRoute"> <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition> </RouteRule> <RouteRule name="default"> <TargetEndpoint>default</TargetEndpoint> </RouteRule> <PostFlow name="PostFlow"> <Request/> <Response/> </PostFlow> </ProxyEndpoint>
Sau đây là các phần chính của ProxyEndpoint này:
- RouteRule được tạo thành mục tiêu NULL với một điều kiện cho yêu cầu OPTIONS. Lưu ý rằng
không có TargetEndpoint nào được chỉ định. Nếu đã nhận được yêu cầu OPTIONS cũng như nguồn gốc và
Tiêu đề của yêu cầu Access-Control-Request-Method không rỗng, proxy ngay lập tức trả về
Các tiêu đề CORS trong phản hồi cho ứng dụng (bỏ qua mục tiêu "phần phụ trợ" mặc định thực tế).
Để biết thông tin chi tiết về điều kiện luồng và RouteRule, hãy xem Điều kiện có biến luồng.
<RouteRule name="NoRoute"> <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition> </RouteRule>
- Quy trình OptionsPreFlight được tạo sẽ thêm chính sách Add CORS (Thêm CORS), chứa CORS (Chia sẻ tài nguyên giữa nhiều nguồn gốc)
tiêu đề, cho luồng nếu nhận được yêu cầu OPTIONS cũng như nguồn gốc và
Tiêu đề của yêu cầu Access-Control-Request-Method không rỗng.
<Flow name="OptionsPreFlight"> <Request/> <Response> <Step> <Name>add-cors</Name> </Step> </Response> <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition> </Flow>
Sử dụng giải pháp CORS mẫu
Hiện đã có giải pháp CORS mẫu, được triển khai dưới dạng luồng dùng chung, hiện có trên GitHub. Nhập gói luồng dùng chung vào môi trường của bạn và đính kèm gói đó bằng cách sử dụng flow hook hoặc trực tiếp vào các luồng proxy API. Để biết chi tiết, hãy xem Tệp CORS-Shared-FLow README được cung cấp cùng với mẫu.