הדף הזה רלוונטי ל-Apigee ול-Apigee Hybrid.
לעיון במסמכי התיעוד של
Apigee Edge
שיתוף משאבים בין מקורות (CORS) הוא מנגנון סטנדרטי שמאפשר לקריאות JavaScript XMLHttpRequest (XHR) שמופעלות בדף אינטרנט ליצור אינטראקציה עם משאבים מדומיינים שאינם מקור. CORS הוא פתרון נפוץ למדיניות המקור הזהה שנאכפת על ידי כל הדפדפנים. לדוגמה, אם תבצעו קריאת XHR ל-Twitter API מקוד JavaScript שמופעל בדפדפן, הקריאה תיכשל. הסיבה לכך היא שהדומיין שממנו הדף מוצג בדפדפן שלכם לא זהה לדומיין שממנו מוצג Twitter API. CORS מספק פתרון לבעיה הזו בכך שהוא מאפשר לשרתים להביע הסכמה אם הם רוצים לספק שיתוף משאבים בין מקורות.
תרחיש שימוש אופייני ב-CORS
קוד ה-JQuery הבא קורא לשירות יעד פיקטיבי. אם הקוד מופעל בהקשר של דפדפן (דף אינטרנט), הקריאה תיכשל בגלל מדיניות המקור הזהה:
<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>
פתרון אחד לבעיה הזו הוא ליצור proxy ל-API של Apigee שקורא ל-API של השירות בקצה העורפי. חשוב לזכור ש-Apigee נמצא בין הלקוח (דפדפן במקרה הזה) לבין ה-API של הקצה העורפי (השירות). מכיוון שה-proxy של ה-API פועל בשרת ולא בדפדפן, הוא יכול לקרוא לשירות בהצלחה. לאחר מכן, כל מה שצריך לעשות הוא לצרף כותרות CORS לתגובה של TargetEndpoint. כל עוד הדפדפן תומך ב-CORS, הכותרות האלה מאותתות לדפדפן שאפשר להרחיב את מדיניות המקורות הזהים שלו, וכך לאפשר לקריאה ל-API ממקורות שונים להצליח.
אחרי שיוצרים את ה-proxy עם תמיכה ב-CORS, אפשר לקרוא לכתובת ה-URL של ה-proxy ל-API במקום לשירות לקצה העורפי בקוד בצד הלקוח. לדוגמה:
<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>
צירוף מדיניות ה-CORS ל-PreFlow של ProxyEndpoint
צירוף מדיניות Add CORS לשרת proxy חדש של API
כדי להוסיף תמיכה ב-CORS ל-proxy ל-API, צריך לצרף מדיניות Add CORS ל-proxy ל-API.
המדיניות Add CORS מוסיפה את הכותרות המתאימות לתגובה. בעצם, הכותרות מאפשרות לדפדפן לדעת עם אילו מקורות הוא ישתף את המשאבים שלו, אילו שיטות הוא מקבל וכו'. מידע נוסף על כותרות ה-CORS האלה זמין בהמלצה של W3C בנושא שיתוף משאבים בין מקורות.
צריך לשנות את המדיניות באופן הבא:
- מוסיפים את הכותרות
content-typeו-authorization(נדרש לתמיכה באימות בסיסי או ב-OAuth2) לכותרתAccess-Control-Allow-Headers, כמו שמוצג בקטע הקוד הבא. - באימות OAuth2, יכול להיות שתצטרכו לבצע פעולות כדי לתקן התנהגות שלא תואמת ל-RFC.
<CORS continueOnError="false" enabled="true" name="add-cors"> <DisplayName>Add CORS</DisplayName> <AllowOrigins>{request.header.origin}</AllowOrigins> <AllowMethods>GET, PUT, POST, DELETE</AllowMethods> <AllowHeaders>origin, x-requested-with, accept, content-type, authorization</AllowHeaders> <ExposeHeaders>*</ExposeHeaders> <MaxAge>3628800</MaxAge> <AllowCredentials>false</AllowCredentials> <GeneratePreflightResponse>true</GeneratePreflightResponse> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> </CORS>
הוספת כותרות CORS לשרת proxy קיים
כדי להוסיף את מדיניות ה-CORS ל-proxy ל-API קיים:
במסוף Google Cloud , נכנסים לדף Apigee > Proxy Development > API Proxies.
- בוחרים את ה-proxy ל-API שאליו רוצים להוסיף את מדיניות ה-CORS. פרטי ה-proxy מוצגים בממשק המשתמש של מסוף Google Cloud .
- לוחצים על הכרטיסייה פיתוח.
- בחלונית הניווט, לוחצים על הלחצן + בשורה Policies (מדיניות).
בתיבת הדו-שיח Create policy (יצירת מדיניות), לוחצים על השדה Select policy (בחירת מדיניות), גוללים למטה אל Security (אבטחה) ובוחרים באפשרות CORS.
מזינים את פרטי המדיניות ולוחצים על יצירה.
- בחלונית הניווט, לוחצים על PreFlow בקטע Target Endpoints > default.
- לוחצים על הלחצן + לצד PreFlow בחלונית Request של העורך החזותי.
- בתיבת הדו-שיח Add policy step, בוחרים במדיניות CORS.
לוחצים על הוספה כדי לצרף את המדיניות.
טיפול בבקשות קדם-הפעלה של CORS
בקשת קדם-הפעלה של CORS היא בקשה שנשלחת לשרת כדי לוודא שהוא תומך ב-CORS. תשובות אופייניות לבקשות קדם-הפעלה כוללות את המקורות שהשרת יקבל מהם בקשות CORS, רשימה של שיטות HTTP שנתמכות בבקשות CORS, כותרות שאפשר להשתמש בהן כחלק מבקשת המשאב, הזמן המקסימלי שבו תשובת קדם-ההפעלה תישמר במטמון ועוד. אם השירות לא מציין תמיכה ב-CORS או לא רוצה לקבל בקשות ממקורות שונים מהמקור של הלקוח, מדיניות המקורות השונים של הדפדפן תיאכף וכל הבקשות בין דומיינים שיישלחו מהלקוח כדי ליצור אינטראקציה עם משאבים שמתארחים בשרת הזה ייכשלו.
בדרך כלל, בקשות קדם-הפעלה של CORS מבוצעות באמצעות שיטת HTTP OPTIONS. כששרת שתומך ב-CORS מקבל בקשת OPTIONS, הוא מחזיר ללקוח קבוצה של כותרות CORS שמציינות את רמת התמיכה שלו ב-CORS. כתוצאה מהלחיצת יד הזו, הלקוח יודע מה מותר לו לבקש מהדומיין שאינו המקור.
מידע נוסף על בקשות מקדימות מופיע בהמלצה של W3C בנושא שיתוף משאבים בין מקורות (CORS). בנוסף, יש בלוגים ומאמרים רבים בנושא CORS שאפשר לעיין בהם.
Apigee לא כולל פתרון קדם-הפעלה של CORS כברירת מחדל, אבל אפשר להטמיע אותו כמו שמתואר בקטע הזה. המטרה היא שה-proxy יעריך בקשת OPTIONS בזרימה מותנית. לאחר מכן, ה-proxy יכול לשלוח תשובה מתאימה בחזרה ללקוח.
הנה תרשים זרימה לדוגמה, ואחריו הסבר על החלקים שמטפלים בבקשת קדם-הפעלה:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
<Description/>
<Flows>
<Flow name="OptionsPreFlight">
<Request>
<Step>
<Name>add-cors</Name>
</Step>
</Request>
<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>החלקים העיקריים של ProxyEndpoint הם:
- נוצר RouteRule ליעד NULL עם תנאי לבקשת OPTIONS. שימו לב:
לא צוין TargetEndpoint. אם מתקבלת בקשת OPTIONS וכותרות הבקשה Origin ו-Access-Control-Request-Method אינן null, ה-proxy מחזיר מיד את כותרות ה-CORS בתגובה ללקוח (תוך דילוג על יעד ברירת המחדל בפועל של ה-backend).
פרטים על תנאי זרימה ועל RouteRule מופיעים במאמר תנאים עם משתני זרימה.
<RouteRule name="NoRoute"> <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition> </RouteRule> - נוצר תהליך OptionsPreFlight שמוסיף מדיניות CORS, שמכילה את כותרות ה-CORS, לתהליך אם מתקבלת בקשת OPTIONS וכותרות הבקשה Origin ו-Access-Control-Request-Method לא ריקות.
<Flow name="OptionsPreFlight"> <Request> <Step> <Name>add-cors</Name> </Step> </Request> <Response/> <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition> </Flow>