שיתוף מידע בין מערכות באמצעות Cookies
פוסט זה כולל טיפ קצר בנושא פיתוח Front End. אם אתם רוצים ללמוד יותר לעומק על פיתוח Front End מהבסיס ועד הנושאים המתקדמים תשמחו לשמוע שבניתי קורס וידאו מקיף בנושא זה הכולל מעל 50 שיעורי וידאו והמון תרגול מעשי.
למידע נוסף והצטרפות לקורס בקרו בדף קורס Front End באתר.
בארכיטקטורת Micro Services מערכות שונות צריכות להעביר מידע אחת לשניה על פעולות של המשתמש. היעזרות במשתמשים עצמם בתור דוורים שמעבירים את המידע בין המערכות חוסך סיבוכים בצד השרת, אבל כולל אתגרים משלו. הנה כמה מהם.
1. מתי רלוונטי
יש שלוש גישות מרכזיות לשיתוף מידע בארכיטקטורת Micro Services:
הראשונה היא העברת הודעות בין Services שונים. בצורה כזאת כל Service אחראי על תחום פעילות מסוים וכאשר מספר Services צריכים לשתף מידע הם נעזרים ב Service שלישי עבור המידע המשותף. לדוגמא, אם יש לנו מספר מערכות שצריכות להכיר את המשתמש הנוכחי, פתרון בגישה זו יחייב פיתוח Service עבור אימות משתמשים שינפיק לכל משתמש Token, וכל Service אחר יפנה לאותה מערכת אימות עם ה Token לבדוק מי המשתמש.
גישה שניה היא לאפשר למספר Services לגשת למידע משותף. בגישה זו אם שתי מערכות צריכות מידע על המשתמש הנוכחי יקראו שתיהן את מזהה המשתמש מה Session Cookie ויפנו ל Redis כדי לקבל את המידע עצמו.
והגישה השלישית אותה אציג בפוסט מעבירה את האחריות למשתמש. בגישה זו נשמור את כל המידע המשותף ב Cookie או באיזשהו Token שנשלח ל JavaScript, ובאחריות הגולש לשלוח Cookie זה לכל מערכת שצריכה אותו. ההבדל המרכזי בין גישה זו לגישה הראשונה הוא שכאן ה Cookie שומר את המידע עצמו, בעוד שבגישה הראשונה נשמר רק ״כרטיס״ באמצעותו ניגשים למידע.
יתרון הגישה השלישית הוא שלא צריך לפתח Service ייעודי לתיווך בין שתי המערכות, וגם אין צורך לשתף פרטי גישה לבסיס נתונים או Redis משותף.
2. איך זה עובד
בשביל ש Cookie ישותף בין מספר מערכות עלינו לשים את כל המערכות באותו דומיין. שרת nginx הוא דרך מאוד נוחה לחבר נתיבים שונים במערכת למערכות שונות. למשל ההגדרה הבאה:
location /php {
include fastcgi.conf;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_param HTTP_PROXY "";
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
}
location /app {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto 'https';
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3000;
}
תפנה נתיבים שמתחילים ב php לפיענוח דרך PHP ונתיבים שמתחילים ב app יועברו לאפליקציה שמאזינה על פורט 3000. כך יוצא שמבחינת הדפדפן מעברת בין המערכות הוא בסך הכל מעבר בין נתיבים שונים באותו אתר, ולכן לכל מערכת גישה ל Cookies שיוגדרו במערכות האחרות.
3. חשוב לשים לב: חתימה
מאחר והמידע עובר בין מערכות דרך הלקוח מומלץ מאוד לחתום על המידע באמצעות HMAC. בדרך זו מי שיש לו מפתח סודי מסוים יכול לחתום על המידע, ומערכות אחרות שיש להן את אותו מפתח סודי יכולות לוודא שהמידע אכן לא שונה מאז שחתמו עליו.
ב PHP אפשר להשתמש בפונקציה hash_hmac
כדי לייצר חתימה:
$sig = hash_hmac('sha256', $string, $secret)
4. חשוב לשים לב: הצפנה
בחלק מהמקרים המידע שתעבירו בין המערכות הוא מידע רגיש ולכן כדאי להצפין אותו כדי שמשתמש לא יוכל אפילו לראות את הפרטים שעוברים. בהרבה מערכות זה לא הכרחי ואפשר להסתפק בחתימה.
ב PHP נוכל להשתמש בספריה PHP-AES כדי להצפין או לפענח באמצעות AES. הקוד נראה כך:
$key = new AES\Key('topsecret');
$nonce = 'abcdefghijklmnop';
$ctr = new AES\CTR;
$ciphertext = $ctr->encrypt($key, $nonce, $plaintext);
החליפו את המילה topsecret בסיסמא סודית שלכם (נקראת המפתח). בתור nonce אפשר לבחור כל ערך אקראי שתרצו, ואין צורך לשמור אותו בסוד.
5. חשוב לשים לב: Replay
מתקפה אחת שאי אפשר למנוע בארכיטקטורה כזו נקראת Replay Attack. המשמעות שלה זה שהלקוח ישלח את המידע שנתתם לו לשמור מספר פעמים או בזמן שלא בדיוק ציפיתם לו.
נניח לדוגמא שאנו בונים מערכת (עקומה) של חנות שמורכבת משלוש תתי מערכות: מערכת קטלוג מוצרים, מערכת מחירים ומערכת סליקה. לקוח בוחר מוצר במערכת הקטלוג, מקבל חזרה מזהה מוצר, פונה איתו למערכת המחירים לקבל את המחיר ואז פונה עם מזהה המוצר והמחיר למערכת הסליקה כדי לשלם.
במצב כזה לקוח מתוחכם יכול בקלות לדלג על מערכת המחירים ולהשתמש במחיר ישן עבור מוצרים אחרים: תחילה פונה למערכת לקבל פרטים של מוצר זול (מזהה מוצר + מחיר), לאחר מכן פונה לקבלת מזהה מוצר של מוצר יקר ומעביר למערכת הסליקה את המחיר שקיבל על המוצר הזול בצירוף מזהה המוצר של המוצר היקר.
כל המידע שעובר בין המערכות בשיטה זו הוצפן ונחתם, ובכל זאת הלקוח יוכל לקבל מוצרים בהנחה משמעותית.