הדף הזה רלוונטי ל-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 של cross-origin להצליח.
אחרי שיוצרים את ה-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 לפרוקסי 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 שאפשר לעיין בהם.
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 אינן null.
<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>