מערכת לוגאין ו - jwt token

אני עובד על יצירת מערכת ההתחברות וניהול משתמשים. סיפריית fastapi-login, שעליה בניתי בלקיחת הטיקט, התבררה לאחר שלושה ימי חפירות בתוכה, כחסרת פונקציונליות ודוקיומנטציה שמאפשרת לעבוד איתה, לכל הפחות אני לא הצלחתי.
נאלצתי לזנוח את הניסיון ליישם איתה, ולבנות מערכת בעצמי.
האופן שבו הגנה על ראוטים בפאסט API עובד, הוא הגדרת דיפנדנסי של JWT בכניסה לראוט. ההגדרה הזאת מייצרת בדיקה של הימצאות token ב- header של בקשת הכניסה לראוט.
יצרתי ראוט לוגאין שמקבל נתונים מטופס התחברות, מאמת את המשתמש, ומייצר jwt token עבור המשתמש.
כל הדוקומנטציה, וכל המדריכים שמצאתי, מגיעים עד הנקודה הזאת, ומחזירים את הטוקן מהראוט שייצר אותו, כג’ייסון.
מכיוון שאנו בונים אפליקציה מונוליטית, אני צריך לצרף את הטוקן ל- headers של הריקווסט שבערך ההחזר של הראוט.
מישהו התנסה במשהו כזה ויכול קצת לעזור?
נ.ב. אני יודע שהרבה מחכים לסיום הטיקט הזה, ואני ממש מתנצל שעדיין לא סיימתי אותו, אבל זה התברר כמשהו הרבה יותר מורכב ליישום בפאסט API מאשר בפלאסק, וזה פשוט לוקח לי מעט יותר זמן ממה שהערכתי במקור.
עריכה:
בניסיון לעבוד עם פלאסק לוגאין, הצלחתי להגיע למצב שהיא גם יוצרת טוקן עבור המשתמש, ומחזירה אותו, בדיוק באותו האופן. הדוקומנטציה שלה מסתיימת שם, והיא משתמשת בדיפנדנסי משלה להגנה על ראוטים.
אז בעצם היא מביאה עד לאותה הנקודה שאני נמצא בה, עם מספר חסרונות:
בשונה מפלאס לוגאין, אין לה שום פונקציונליות של לוגאאוט.
בנוסף, אין לה שום פונקציונליות של current_user. כל מה שהיא מייצרת זה טוקן.
מעבר לכך, אין שום דבר בדוקמנטציה שלה, ואין אף מדריך שאני מצאתי, שמסביר עליה משהו. ההחלטה לזנוח אותה היתה בשיקול שעדיף לי להגיע לנקודה הזאת של יצירת טוקן בעצמי, כשאני מסתמך ישירות על OAuth2 ו- JWT, שלהם יש הרבה יותר דוקומנטציה, והסיכויים ליישם את הפונקציות הללו הרבה יותר גבוהים, כשגם יש לי גישה לפרטים של יצירת הטוקן וכל הלוגיקה.
בכל אופן, יש לי קובץ שמיישם את fastapi-login, אותו לא העליתי לריפו, למי שמעוניין להתנסות

2 לייקים

אין לי ניסיון, אבל אשמח לנסות לעזור איכשהו :pray:t2:
אתה יכול לחדד מה בדיוק אתה צריך? והאם אפשר להעיף מבט על הקוד שלך כדי להבין מה קורה שם? :heart:

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

אני גם לא ממש מבין בזה.
אבל להעביר מידע מסויים מעמוד לעמוד - זה לא מה שאפשר לעשות עם session ?
או שאי אפשר להעביר מידע כזה שם ?

אני לא יודע לגבי זה, אני גם חסר ניסיון עם הפעולות הללו

מציע אם ככה לנסות לבדוק א םזה אפשרי - הרי אנו מעבירים עם session מידע של המשתמש (שם משתמש, user id וכו) וזה עוזר לנו לזהות אותו בעמודים אחרים - לפחות ככה עשינו בפרויקט קודם.

אולי שווה לנסות לבדוק את הכיוון הזה

לייק 1

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

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


בכ"מ, גיגלתי FastAPI GitHub כדי לראות מה המודולים המומלצים. הגעתי למאגר מודולים שנקרא Awesome FastAPI. נכנסתי לכל הקישורים שקשורים לאותנטיקציה, ובדקתי למה יש הכי הרבה כוכבים.
נראה שהמודול FastAPI Users מאוד אפוי. הייתי מציע להסתכל עליו.

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

4 לייקים

אחרי המון המון חפירות, מתברר שהרבה אחרים נתקלו בבעיה הזאת. זה נראה שבמקור, fastapi מתוכננת לבניית api ולא לתכנון של בקאנד שמנהל סשן. זאת הסיבה שכל הדוקומנטציה והמדריכים השונים מסתיימים בנקודה שבה מוחזר טוקן ללקוח, ומתמקדים בייצור ובאימות שלו כאשר הוא מתקבל בחזרה. ניסיתי גם ליצור פונקצית middleware, שתעביר לי בכל פעם את הטוקן מהבקשה לריספונס, אך לא הצלחתי ליישם את זה, ואני לא יודע אם זה אפשרי בכלל. זהוא רעיון תיאורטי שחשבתי עליו, אבל לא נתקלתי בו בשום מקום בגוגל.
הפתרון שכן מצאתי, הוא אכסון של הטוקן ב- htttpcookie. לקח לי המון זמן למצוא את זה. מבדיקה שעשיתי, אני מבין שזה מאובטח, מכיוון שאף קוד JS אינו יכול לגשת למידע שם, או לשנות אותו. מהבחינה הזאת זה בטוח.
פתרון נוסף שמצאתי, הוא אכסון הטוקן ב- session cookie בשרת. זה יותר מאובטח מקוקי רגילה, מאחר וזה לא נשלח ללקוח, אך זה פרוץ למניפולציה על ה- session. ולהבנתי, פתרון פחות טוב מהקודם. אני מניח שהידע שלך קצת הרבה יותר רחב משלי, אז אשמח לשמוע את דעתך.
בנוגע fast-api users: קראתי חלקים נרחבים מהדוקומנטציה. זאת ספרייה מאוד גדולה. להבנתי, היישום שלה ייאלץ לבצע המון שינויים. היא משתמשת במודל יוזר מוגדר שממנו צריך לרשת, וזה יאלץ המון שינויים לדעתי בהרבה מהטיקטים. מעבר לכך, כל הרג’יסטר שעשיתי כנראה יילך לפח, כי זה נראה שלא ניתן להפריד בין הפעולות. מהסיבות הללו אני מנסה בכ"ז למצוא פתרון אפשרי אחר, מבלי להשתמש בסיפרייה הזאת.
אם אתה, או מישהו אחר התנסה ביצירת ראוט middleware ויודע אילו פעולות ניתן לעשות ואילו פעולות לא ניתן לעשות, אז אשמח לדעת אם זה אפשרי, מכייוון שזהוא פתרון קלאסי. הסשן נשמר מאובטח ברמה של JWT לכל אורכו, ומערכת האבטחה עובדת כאילו זה api לכל דבר וענין. הפעולה הספציפית שלא הצלחתי לעשות היא תפיסת הטוקן מהריספונס שחוזר מהלוגאין.

5 לייקים

נכון, זה באמת הפתרון שמקובל על פי רוב.

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

לא התרשמתי שמדובר במודול גדול למען האמת, והוא כן מאוד מתאים לצרכים שלך. אולי שווה לשקול את זה שוב.

זה פתרון אחלה אם אתה יודע לעבוד עם JWT בצורה טובה.
שים לב שיש טעויות אבטחה נפוצות ב־JWT שחשוב לא לעשות וכדאי לקרוא על זה (יש הרבה מאמרים שם בחוץ)

אפשר הצצה לאיך נראה הקוד שמחזיר את הטוקן, ובעזרת איזה קוד (ואיפה) אתה מנסה לתפוס אותו?

לייק 1


זה פחות או יותר הקוד שמחזיר את הטוקן. אמור להיות return response בסוף.


זאת בערך הפונקצית מידלוור. אני יודע שזה נראה נורא, עשיתי המון ניסיונות. הקוד כרגע במצב שהוציא ארור.מאוד יכול להיות שיש פה טעויות בסיסיות מאוד, אני פשוט ממש לא מכיר את הנושא, וניסיתי ‘לירות לכל הכיוונים’, עד שמשהו יתפוס. פשוט בשלב מסוים זנחתי את זה. אני מקווה שיהיה לך מובן מה ניסיתי לעשות פה.
עדכון: ההבדל בין “Authorization” ל- “authorization” טופל בשלב כלשהו. זאת לא הבעיה…

לייק 1

אז הפתרון של httpcookie הוא כזה שמקובל עליך? פשוט ממש עמדתי להתקין את fastapi-users ולעשות את זה איתה.
בנוגע לכל הקשור ליצירת הטוקן שעשיתי, והאימות שלו, יש פה בפוסט קישור לגיטהאב שלי. הקוד הזה שם, בברנצ’ login. רק כדי שתראה שהאופן בו יישמתי את זה הוא מספיק טוב ובטוח. תודה רבה רבה על התשובות המפורטות

לייק 1

נשמע מצוין, איפה הפער? :slight_smile:

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

זה נשמע קצת יותר מסובך.
למה לא להשתמש בשלד שלהם?

בכנות זה נראה כאילו יש פה משהו כמעט מוכן

אולי לא התנסחתי באופן ברור…
הכוונה שלי היתה:
אופציה א: השארת מה שעשיתי בעניין האבטחה, והוספת httpcookie לקבלת הטוקן חזרה מהלקוח.
אופציה ב: בלי httpcookie, בלי האבטחה שלי, ואולי בלי הרג’יסטר. הכל ע"י fastapi users, ובדיקה במהלך היישום אם את הרג’יסטר שלי בכל זאת אפשר להציל.
לי אין שום העדפה, באמת. אשמח להתנסות גם בסיפרייה הזאת, באותה מידה שאשמח שהקוד המקורי שלי ייושם.

הייתי שמח ללכת על ב’. אני מניח שהם משתילים את ה־JWT בתור HTTPOnly Cookie בעצמם :slight_smile:

2 לייקים