ניהול Sessions ב־CppCMS

ב־29.12.2008, מאת ארתיום; פורסם תחת: תכנה חופשית, אינטרנט, פיתוח, תכנה ומחשבים, CppCMS, C++‎‏; ‏9 תגובות

הערה 05/01/2009: פורסם מדריך לעבודה עם sessions בויקי

אחד החלקים חשובים של כל תשתית פיתוח יישומי אינטרנט הוא --- תמיכה בניהול Sessions: שמירת מידע בין בקשות שונות. זה מאפשר להפוך פרוטוקול HTTP שהוא stateless בטבעו ל־statefull. זהו מרכיב הכרחי שקיימ ברוב התשתיות כמו Django או RoR.

בד"כ, אני נוהג להסתכל בפתרונות הקיימים, לבחור את הטוב ביותר וליישמו במסגרת האילוצים של CppCMS. גם הפעם הסתכלתי בשתי התשתיות הפופולריות RoR ו־Django והבנתי, שהפתרון שהם מציעים, כפי שהוא לא מתאים בגלל אילוצי ביצועים.

הדרך "זולה" ביותר, היא לשמור את המידע ב"עוגיות" אבל יש לה שני מגרעות:

  1. יש מגבלה של כ־4K נתונים שניתן לשמור בעוגיה (לא כולל קידוד וכד').
  2. RoR שנותנת אפשרות ניהול מידע בעוגיות, לא מבטיחה שהמידע השמור לא ייחשף ללקוח --- תחשבו על פתרון Captcha ששמור בתוך עוגיה..

שמירת המידע בצד השרת כרוכה בשתי בעיות:

  1. ניהול בסיס נתונים כלשהו לשמירת המידע --- שיכול להוות צוואר בקבוק.
  2. בעית הביזור שלו גישה מרובת משתמשים.

לכן, החלטתי שב־CppCMS אני אלך על פתרון קצת שונה שמשלב את התכונות של שניהם (עם שיפורים).

התשתית

  1. או שהמידע תישמר ב"עוגיות" בצורה מוצפנת עם מפתח פרטי.
  2. או שהמידע תישמר בבסיס הנתונים (מובזר), כאשר המפתח יישמר בעוגיה.
  3. או שניהם --- אם גודל המידע נמצא מתחת לסף מסוים, אז כל המידע נשמר בעוגיות חתומות ו/או מוצפנות. אחרת, המידע נשמר בצד השרת, ובכך מוריד את העומס למקרים , ככל הנראה נדירים בהם גודל העוגיות לא מספיק.

ניהול מידע בעוגיות

למשתמש יהיו שתי אפשרויות בחירה:

  • לשים חתימה דיגיטלית HMAC‏ על המידע כדי להבטיח את הקונסיסטנטיות.
  • לשים הצפנת AES‏ וחתימה על המידע שיבטיח גם סודיות

    שימוש ב־AES מגדיל את תוכן העוגיות בכ־32 בתים, ודורש ש־CppCMS יקומפל עם ספריית gcrypt, אבל, נותן בטחון בשמירת מידע "מסווג" בצד הלקוח.

ניהול מידע בצד השרת

יסתמך על מספר אפשרויות ניהול המידע לפי Session ID:‏

  1. שמירה ב־Cache --- לא אמינה ומתאימה בעיקר לבדיקות.
  2. שמירה בקבצים --- כולל אפשרות ביזור מעל NFS התומך בנעילות.
  3. שמירה בבסיס נתונים של sqlite3.‏
  4. 2 ו־3 רק מבוזר מעל רשת בעזרת פרוטורול TCP/IP.

שילוב השיטות.

  • ניתן להגדיר שמירה בצד הלקוח או והן בצד השרת כתלות בגודל המידע השמור.
  • ניתן להרחיב כל אחד מהמנגנונים. למשל ליצור שמירה בצד השרת בבסיס הנתונים אחר המתאים ליישום שאותו מפתחים.

ממשק המפתח

מבחינת המפתח בחירת התשתית שקופה לחלוטין וניתנת לשינוי בקובץ הגדרות פשוט.

הגישה למידע ששמור ב־session היא גישה של "מילון" של מפתח/ערך. ניתן לשמור בו מחרוזות או ערכים כלשהם שאותם רוצים להעביר, לדוגמה:

user_id=session.get<int>("user_id");
user_name=session["username"];

או שמירת אוביקט שלם:

struct user_data : public serializable {
    int id;
    string first_name,second_name;
    double age;
    ...
};

...

user_data usr;
session["user"]=usr;

כרגע הפיתוח עדיין בנמצא עיצומו בענף svn‏ -- "sessions" ובימים הקרובים צפוי להתמזג ל־trunk.

תגובות

elcuco, ב־29.12.2008, 21:54

אתה צוחק עליי?

אתה יושב ומבלבל את השכל על הדברים הכי לא מעניינים שיש... ואת הפנינה החשובה באמת אתה שומר לסוף...

איך אתה ממזג ענפים ב־svn...?!?!??!

ארתיום, ב־29.12.2008, 22:14

איך אתה ממזג ענפים ב־svn...?!?!??!

דיאגו, לפעמים אני ממש לא מבין אותך...

  • אם אתה ציני, אז מה היה כל־כך נוראה בפוסט שהוספת את ההערה.
  • אם אתה באמת שואל, אז אני ממש לא מבין כיצד זה יכול להיות שאתה לא יודע דבר כל־כך בסיסי.
  • אולי אני כתבתי שטות, אולי העברית שלי לא בסדר ואתה צוחק עליי ואני לא קולט.
עידו, ב־29.12.2008, 23:45

תשתמשו ב svnmerge.py, הוא מגיע לרוב עם svn, אפשר להוריד אותו מ http://www.orcaware.com/svn/wiki/Svnmerge.py והוא למעשה נכנס לתוך svn מגירסא 1.5.

מאז שעברתי ל svnmerge.py החיים הרבה יותר פשוטים. עדיין יש מדי פעם בעיות אבל רובן נפתרו רק מהשימוש בנ"ל.

אגב, יש אפשרות לפצל את המידע על מספר עוגיות. אפשר לשמור לפחות 20 עוגיות פר דומיין, אבל למעשה רוב, אם לא כל הדפדפנים מאפשרים יותר (IE ופיירפוקס מאפשרים 50, ספארי 1000). כמובן שזה מגדיל את נפח ה upload/download בהתאם, מה שמטה את ההעדפה לכיוון של קבצים/DB כי תבלה יותר זמן ברשת מאשר בכל קומבינציה בשרת.

מעניין יהיה לבדוק עבור איזה נפח של מידע עדיף לשמור בשרת ומתי עדיף בעוגיה...

ארתיום, ב־30.12.2008, 0:01

כמובן שזה מגדיל את נפח ה upload/download בהתאם, מה שמטה את ההעדפה לכיוון של קבצים/DB כי תבלה יותר זמן ברשת מאשר בכל קומבינציה בשרת.

זאת שאלה של העדפות עבור פרויקט ספציפי. לכן, לכל אחד יש אופציה לשים את הסף איפה שהוא רוצה או בכלל ללכת תמיד לאחד הכיוונים.

זה מספיק גמיש.

לגבי מיזוג. לפי דעתי, הבעיה היחידה היא לקרוא את התיעוד פעם אחת כמו שצריך (מעשה פרק אחד), לעשות תרגיל מעשי או שניים, משם זה מאוד פשוט.

העניין הוא ש־SVN היא מערכת פשוטה אבל יש בה היגיון מאוד בריא שמאפשר לך בקלות לעשות מיזוגים שונים.

אגב, אני מתייחס עדיין ל־1.4 ללא סקריפטים של צד ג'.

עידו, ב־30.12.2008, 1:17

החלק שציטטת בא בעקבות ההערה שלי על לשמור את המידע במספר עוגיות על מנת לחרוג מהמגבלה של 4K, היא לא כוונה לגבי המימוש שלך. מצטער אם זה לא היה ברור.

שווה לך לבדוק את svnmerge.py, הוא מייעל ומסדר את העבודה של ה merge. כך לדוגמא הוא מייצר לך לוג של השינויים שהולכים להכנס פנימה ל trunk, ומאפשר לך לחסום revisions כדי שלא יעברו merge. לדוגמא, יש לי brunch שבשבילו אני צריך להשתמש בחיבור DB שונה מהחיבור שיש ב trunk, שיניתי את הקונפיגורציה וחסמתי את ה revision הנ"ל. זה מאפשר לי להמשיך לעבוד בלי לדאוג שבטעות הקונפיגורציה של ה branch תכנס ל trunk.

Frank Malina, ב־30.12.2008, 4:47

As far as you don't try to put sessionIDs in the URLs you are on a good way forward

Look at this Djangocon video from Cal Henderson

http://uk.youtube.com/watch?v=i6Fr65PFqfk

He talks about sessions and performance problems in Django at around 38 mins in the video

Frank Malina, ב־30.12.2008, 4:59

He also talks about stashing things in a cookie. It makes a lot of sense for most of applications. Application can give you a cached page and the personalized stuff will be read from the cookie. E.g.: In e-commerce app contents of your shopping cart will be read from the cookie while you browse the cached product pages. Otherwise you'd need to generate the product page for every request just because the shopping cart content is unique for a particular user

ארתיום, ב־30.12.2008, 8:53

otherwise you'd need to generate the product page for every request just because the shopping cart content is unique for a particular user

אכן, זה נכון, חשבתי אולי גם להוסיף API שיאפשר "לחשוף" באופן שקוף חלקים לטובת עבודה בצד הלקוח עם JavaScript.

משהו כמו

session["card_type"]="visa"
session["product"]="toyota"
session.expose("product");

יגרום להווצרות עוגיות:

cppcms_session=6e42fb466a350248a7b8e2b510b3095e
cppcms_session_product=toyota

כאשר שדות מסוימים חשופים, ואפשר יהיה לעבוד איתם ב־JavaScript

רק צריך לחשוב מה עושים עם רשימות וכד'.

CppCMS Blog, ב־5.1.2009, 12:24

Session Management in CppCMS

Session management branch was merged to trunk, now you can use sessions transparently in CppCMS.

Quite full tutorial about sessions in CppCMS was written:

Starting With Sessions Management Sessions with CppCMS (Hebrew) was published as well.

הוסף תגובה:

 
 כתובת דוא"ל לא תוצג
 

ניתן לכתוב תגובות עם שימוש בתחביר Markdown.

חובה לאפשר JavaScript כדי להגיב.

דפים

נושאים