כמה מילים על חיבור חברתי ומסך כניסה חדש לאתר
העליתי אתמול גירסה חדשה של מסך הכניסה לאתר עם אפשרות לכניסה דרך גיטהאב או לינקדאין. מוזמנים לנסות את זה כאן (לא כזה מלהיב, אבל עובד): https://www.tocode.co.il/login
אני משתף כמה הערות טכניות לגבי המימוש:
בכל המדריכים שראיתי הסבירו שצריך להוסיף לטבלת המשתמשים עמודה של "provider" ועמודה של "identifier", וכך כשמשתמש נוצר דרך לוגין חיצוני אפשר למלא את הערכים מתוך המידע שקיבלנו מאותו לוגין חיצוני, כדי שבלוגין הבא דרך אותו שירות נוכל לחבר את הפעולות לאותו משתמש. אבל השיטה הזאת לא מספיק טובה כי בעולם שלנו יש כבר משתמשים קיימים באתר והם ישתמשו בלוגין החברתי כדי להתחבר לחשבון הקיים שלהם, וגם אפשר לדמיין משתמשים שיתחברו פעם מגיטהאב ופעם מלינקדאין. לכן במקום להוסיף עמודות יצרתי טבלה חדשה של "זהויות" וכל פעם שמשתמש מתחבר דרך לוגין חיצוני אני מוסיף שורה לטבלת הזהויות עם הפרטים. כל שורה בטבלת הזהויות מחוברת לשורה בטבלת המשתמשים, וכך למשתמש אחד יכולות להיות מספר זהויות.
הקוד הבא מופעל אחרי שמשתמש עשה לוגין דרך שירות חיצוני כדי להבין מי המשתמש שהגיע:
def self.create_from_provider_data(auth)
authorization = Authorization.find_by(provider: auth.provider, uid: auth.uid)
return authorization.user if authorization
user = User.find_or_create_by(email: auth.info.email) do |user|
user.name = auth.info.name || auth.info.full_name
user.password = Devise.friendly_token[0, 20]
end
user.authorizations.create(provider: auth.provider, uid: auth.uid)
return user
end
הקוד מחפש שורה בטבלת הזהויות, אם הוא מוצא אז הכל קל ומחזירים את המשתמש שמחובר לאותה שורה. אם לא מצא אז הוא מחפש (או יוצר) משתמש עם האימייל שקיבלנו, יוצר שורה חדשה בטבלת הזהויות ומחבר בין השורה החדשה בטבלת הזהויות למשתמש.
שימו לב שהקוד יוצר סיסמה לכל משתמש. זה מעניין כי משתמש שהגיע דרך לוגין חיצוני לא נרשם עם סיסמה. הסיפור כאן הוא של תאימות לאחור, כי בטבלת המשתמשים העמודה של סיסמה אינה יכולה להיות ריקה. זה לא נורא כי זו סיסמה אקראית שאף אחד ממילא לא יודע. אם המשתמש ירצה להתחבר יום אחד עם שם וסיסמה הוא יוכל ללחוץ "שכחתי סיסמה" ולאפס את הסיסמה. אם הייתי מתחיל מאפס את הפיתוח היום כנראה שגם את האפשרות לחיבור עם אימייל וסיסמה הייתי שם בטבלת הזהויות.
החיבור עצמו בריילס ללוגינים חברתיים כמעט לא דורש קוד ומבוצע דרך ג'ם שנקרא omniauth.
במקור רציתי לפתוח לוגין מגוגל וגיטהאב, אבל גוגל החליטו שאני צריך לאמת את זהותי כדי להשתמש בלוגין שלהם וביקשו מכתב הסבר בצירוף וידאו שאמור להראות מה בדיוק אני עושה עם האימייל שיגיע אליי. בינתיים ויתרתי על התענוג. לינקדאין וגיטהאב אפשרו להגדיר לוגין חברתי בלחיצת כפתור.
ובאמת מילה על אתרי הלוגין החברתי - הסיפור זהה בכולם כי כולם משתמשים באותו פרוטוקול: פותחים אפליקציה, מקבלים
client_id
וclient_secret
ומכניסים אותם ליישום שלנו. כן חשוב להגדיר מה כתובת האתר שלנו ביצירת האפליקציה כי הם מוכנים לשים מסך לוגין חברתי רק לאנשים שהגיעו מהאתר שמתאים לאפליקציה שפתחתם. בכל אתר דף ההגדרות בו יוצרים אפליקציה מתחבא במקום אחר, בגיטהאב זה היה ב Developer Settings ובלינקדאין יש פורטל של מפתחים ובו יוצרים אפליקציה. מה שעוד היה מבלבל באתר של לינקדאין זה שצריך לבחור בטאב Products את המוצרSign In with LinkedIn using OpenID Connect
בשביל שהלוגין יעבוד.
סך הכל בזכות omniauth כל החיבורים עבדו יחסית חלק ובזכות טיילווינד הארגון מחדש של מסך הכניסה גם היה פשוט.