כל מפתח ששילב API של צד שלישי פגע באותו קיר: המסמכים אומרים "אמת עם אישור בסיסי," אתה מדביק את המפתח והסוד שלך בבקשה, והשרת עונה עם שטוח 401 Unauthorized ואין רמז למה. תשע פעמים מתוך עשר האישור קודד מעט שגוי, ואין שום דבר בטעות שאומר לך את זה. בניתי וצרכתי מספיק ממשקי API על פני תוספי וורדפרס ו-Laravel backends כדי לבזבז כמות מביכה של זמן בדיוק על זה, אז שמתי א מחולל אישורים בסיסי על Toolz.dev שבונה את הכותרת בצורה נכונה בכל פעם ומפענח אחת בחזרה כאשר אתה צריך לבדוק זה המדריך אליו ולסכימה שמאחוריו.
TL;DR: HTTP Basic Authentication שולח שם משתמש וסיסמה בתור
base64(username:password)בtheAuthorizationכּוֹתֶרֶת. הכלים מחולל אישורים בסיסי הופך שם משתמש וסיסמה לכותרת המדויקת, פקודת curl מוכנה להפעלה, קטע אחזור וטופס פרטי המשתמש של כתובת האתר, והוא מפענח אסימונים קיימים בחזרה. הוא מקודד דרך UTF-8 כך שאישורים שאינם ASCII ישרדו, מזהיר כאשר שם המשתמש מכיל נקודתיים, ופועל כולו בצד הלקוח.
מהו אימות HTTP Basic?
HTTP Basic Authentication היא סכימת האישורים הפשוטה ביותר שהאינטרנט מגדיר. זה מצוין ב RFC 7617, שיושב על גבי מסגרת אימות ה-HTTP הכללית ב RFC 7235. הרעיון הוא מינימלי: כדי להוכיח מי אתה, אתה שולח Authorization כותרת שערכה הוא המילה Basic, רווח, ולאחר מכן קידוד base64 של שם המשתמש והסיסמה שלך שמצטרף על ידי נקודתיים בודדת.
באופן קונקרטי, אם שם המשתמש שלך הוא admin והסיסמה שלך היא secret, הלקוח יוצר את המחרוזת admin:secret, מקודד אותו כ-UTF-8 בתים, base64-מקודד את הבתים האלה לקבל YWRtaW46c2VjcmV0, ושולח:
Authorization: Basic YWRtaW46c2VjcmV0
זה כל הסכימה אין לחיצת יד, אין nonce, אין hashing הפשטות שלה היא בדיוק הסיבה שהיא שרדה: זה טריוויאלי ליישם בשני הקצוות, ועבור כלים פנימיים, רישומים פרטיים, webhooks, ו APIs אינספור זה עדיין ברירת המחדל המלכוד, וזה אחד גדול, הוא שהקידוד הוא הפיך לחלוטין, אשר מעצב הכל על איך אתה צריך להשתמש בו.
האם קידוד base64 זהה להצפנה?
לא, וזה הדבר החשוב ביותר שיש להבין לגבי אישור בסיסי. Base64, מוגדר ב RFC 4648, הוא קידוד תחבורה מטרתו היא לייצג נתונים בינאריים או טקסט באמצעות קבוצה בטוחה של 64 תווים להדפסה כך שהוא שורד נשלח דרך מערכות שמצפות לטקסט. זה לא צופן, הוא לא משתמש במפתח, והיפוך זה לוקח צעד אחד כל מי שיכול לראות YWRtaW46c2VjcmV0 יכול לפענח אותו בחזרה ל admin:secret באופן מיידי, וזה מה שעושה מצב הפענוח של הכלי 's.
התוצאה היא שאימות בסיסי מספק אפס סודיות בפני עצמו. האישור נשלח למעשה בצורה ברורה, רק לבוש בתחפושת דקה. זו הסיבה שהכלל היחיד שאינו ניתן למשא ומתן של אישור בסיסי הוא שהוא חייב לנסוע רק דרך HTTPS. TLS מצפין את כל הבקשה, כולל ה Authorization כותרת, כך שאישור base64 מוגן במעבר שלח אישור בסיסי באמצעות HTTP רגיל ופרסמת את הסיסמה שלך לכל מי שנמצא בנתיב הרשת.
אני עובד על הנקודה הזו מכיוון שצעד ה-base64 מטעה אנשים לחשוב שהאישור מקושקש בצורה משמעותית כלשהי. זה לא. התייחס לאסימון base64 באותה זהירות שהיית מתייחס לסיסמה הגולמית, כי הם ניתנים להמרה הדדית באופן טריוויאלי. ה כלים מקוונים לפרטיות נתונים המדריך מכסה מדוע הכלי הזה עושה את הקידוד בדפדפן שלך ולא בשרת, מה שעבור אישור חי הוא כל העניין.
כיצד בנויה כותרת האישור הבסיסית, צעד אחר צעד?
הבנייה היא ארבעה שלבים קטנים, וטעות קלה של כל אחד מהם מייצרת אישור שנכשל בשקט:
- הצטרף עם נקודתיים. יוצרים את המחרוזת
username:password. המעי הגס הוא המפריד. - מקודד כ-UTF-8. הפוך את המחרוזת הזו לבייטים באמצעות UTF-8. זה חשוב עבור כל תו שאינו ASCII.
- Base64-מקודד את הבתים. החל base64 סטנדרטי כדי לייצר את האסימון.
- קידומת עם
Basic. ערך הכותרת הסופי הואBasicואחריו האסימון.
ה גנרטור עושה את כל הארבעה ומעביר לך את הכותרת המוגמרת. זה גם מייצר את הטפסים שאתה מדביק בפועל לתוך מסוף או בסיס קוד: פקודת curl המשתמשת ב- -u דגל, פקודת תלתל עם המפורש -H 'Authorization: Basic ...' כותרת, קטע אחזור, האסימון החשוף בפני עצמו וטופס פרטי המשתמש של כתובת האתר https://user:pass@host. משימות שונות רוצות צורות שונות, והקלדה מחדש של ה-base64 ביד היא בדיוק המקום שבו מתגנבות טעויות.
למה שם המשתמש משנה יותר מהסיסמה?
יש אסימטריה אחת בתכנית שמכשילה אנשים כל הזמן, והיא מגיעה היישר מהשלב הראשון. האישור מפוצל על ראשון נקודתיים. זה אומר ששם המשתמש לא יכול להכיל נקודתיים, מכיוון שהשרת יקרא את הנקודתיים הראשונה בשם המשתמש שלך כגבול וימסור את השאר לשדה הסיסמה. הסיסמה, לעומת זאת, יכולה להכיל כמה נקודתיים שהוא אוהב, מכיוון שהכל אחרי הנקודתיים הראשונה הוא הסיסמה.
RFC 7617 מציין זאת ישירות: מזהה המשתמש לא חייב להכיל נקודתיים. קל להפר את זה מבלי לשים לב, במיוחד כאשר שם המשתמש הוא בעצמו משהו בנוי כמו מפתח API או מזהה בצורת דואר אלקטרוני שבמקרה כולל נקודתיים. המחולל צופה בדיוק בזה ומזהיר אותך כאשר שם המשתמש מכיל נקודתיים, מכיוון שהאישור המתקבל יפענח עם הפיצול במקום הלא נכון ויפיק 401 שלא נותן לך מושג לגבי הסיבה.
הנה הכלל בטבלה, כי שווה להיות חד משמעי.
| שדה | עשוי להכיל מעי גס? | סיבה |
|---|---|---|
| שם משתמש | לא | המעי הגס הראשון הוא המפריד |
| סיסמה | כן | הכל אחרי נקודתיים הראשונה היא הסיסמה |
ניפיתי באגים בכשל המדויק הזה בטבע, שבו שירות הוציא API "usernames" שהכיל מדי פעם נקודתיים והשילוב עבד עבור רוב הלקוחות ונכשל באופן מסתורי עבור כמה. אזהרת הכלי's הייתה חוסכת באותו אחר הצהריים.
מדוע קידוד UTF-8 משנה?
עבור שם משתמש וסיסמה של כל ASCII, שלב הקידוד אינו נראה; כל תו הוא בית אחד ו-base64 עושה את שלו. ברגע שאישור מכיל אות מודגשת, סקריפט לא לטיני או אימוג'י, קידוד הבתים הופך למכריע. RFC 7617 ממליץ על UTF-8 בדיוק כך שהלקוח והשרת יסכימו על הבתים עבור התווים הללו.
מקודד נאיבי שמניח שתו אחד הוא בייט אחד, או שנשען על API של דפדפן עם התנהגות מדור קודם, ישחית café או пароль לתוך הבתים הלא נכונים, ואת אסימון base64 זה מייצר לא יתאים מה שרת תואם מחושב מאותו credential התוצאה היא עוד שקט 401. מחולל זה מקודד את credential מעל UTF-8 ביד, אז סיסמה כמו café:naïve מייצר בדיוק את הבתים שלקוח RFC 7617 היה שולח, וצד הפענוח הופך אותו בנאמנות. אם אי פעם היה לך אישור שעבד עבור חבר צוות אחד ולא אחר, תו שאינו ASCII המקודד באופן לא עקבי הוא חשוד עיקרי.
כיצד אוכל לפענח אסימון אישור בסיסי?
מכיוון שהקידוד הפיך, בדיקת אישור קלה כמו הפקת אישור. קח את החלק שאחרי Basic , base64-פענח אותו, קרא את התוצאה כ-UTF-8, ופצל על המעי הגס הראשון. ה generator's מצב פענוח עושה זאת: הדבק מלא Authorization: Basic ... קו, חשוף Basic ... ערך, או רק האסימון, והוא מראה לך את שם המשתמש והסיסמה שהוא נושא.
זה באמת שימושי, לא רק קוריוז כאשר אתה מקבל אישור עובד ומתבקש לשחזר אותו בסביבה חדשה, הפענוח אומר לך בדיוק איזה שם משתמש וסיסמה הוא מקודד כדי שתוכל להגדיר אותם בצורה נכונה כאשר אינטגרציה נכשלת, פענוח האסימון אתה בעצם שולח ומשווה אותו למה שהתכוונת הוא לרוב הדרך המהירה ביותר לזהות רווח תועה, שדה שגוי או נקודתיים במקום הלא נכון. וזו תזכורת חיה לנקודת הסודיות שלמעלה: אם אתה יכול לפענח את זה בקלות, כך יכול כל מי שיירט את זה באמצעות HTTP רגיל.
איפה הגנרטור מתאים עם הכלים האחרים
אישור בסיסי הוא אחד מכמה כלי אישורים ובקשות באתר החולקים את אותו מודל של צד לקוח, ללא העלאה. כאשר האסימון שאתה בודק הוא אסימון נושא ולא אישור בסיסי, ה מפענח JWT קורא את הטענות מתוך אסימון אינטרנט של JSON. כאשר אתה צריך hash ולא קידוד, עבור סכום בדיקה או תקציר סיסמה, ה מחולל hash מחשב את זה. כאשר אתה רק רוצה לקודד או לפענח בסיס 64 שרירותי ולא אישור ספציפי, ה ממיר base64 מטפל במקרה הכללי. וכשאתה מאתר באגים בבקשה עצמה ורוצה לדעת איזה לקוח שלח אותה, ה מנתח סוכן משתמש קורא את הכותרת User-Agent.
למפה רחבה יותר של האופן שבו כלי עזר אלה לבקשה ותגובה עובדים יחד, ה ערכת כלים למפתחי אינטרנט roundup עובר דרך סשן איתור באגים מציאותי, וה- כלי פרודוקטיביות למפתחים כריכות מדריך הרכבת סט אישי שלהם. אישור בסיסי עולה רק לעתים רחוקות בבידוד; זה בדרך כלל שורה אחת בבקשה שאתה מנסה לגרום לעבודה.
דוגמה עובדת: חיווט אינטגרציה של API
תן לי לקרקע את זה במשימה שאני הכי מכה. אתה משלב שירות של צד שלישי שהמסמכים שלו אומרים לאמת עם אישור בסיסי באמצעות מפתח API כשם משתמש וסיסמה ריקה, או מפתח וזוג סודי. המסמכים נותנים לך את האישורים אבל לא את הכותרת, והבקשה הראשונה נכשלת.
הנתיב האמין הוא לבנות את הכותרת במפורש ולבדוק אותה עם תלתל לפני שאתה כותב שורה של קוד יישום. הדבק את המפתח והסוד לתוך גנרטור, העתק את curl -H טופס, ולהפעיל אותו נגד נקודת קצה ידועה.If curl מצליח והקוד שלך לא, הבעיה היא בקוד שלך's לבקש בנייה, לא את האישור, ויש לך רק לחתוך את שטח החיפוש בחצי אם curl גם נכשל, האישור עצמו שגוי, ופענוח האסימון מאשר בדיוק איזה שדה כבוי.
בתוסף וורדפרס אני צריך לעתים קרובות לקרוא ל-API חיצוני מ-PHP, וערך הכותרת הנכון הוא מה שאני מזין אליו wp_remote_get דרך ה Authorization טיעון כותרת. ב-Laravel זה נכנס ל- withHeaders התקשר ללקוח HTTP, או שאני משתמש ב-framework's withBasicAuth עוזר, שבונה לי את אותה כותרת כך או כך, בעל ערך הכותרת הידוע-טוב מהמחולל אומר שאני מאתר באגים בקוד הבקשה שלי מול אישור שכבר הוכחתי שעובד, במקום מאתר באגים בשניהם בבת אחת. מקרה הסיסמה הריקה הוא המקום שבו המחולל מרוויח את השמירה שלו, כי קל לשכוח את זה key: עם נקודתיים נגררת הוא אישור שונה, ולעתים קרובות נכון, מ key לבד.
המשמעת האחרונה היא זו האבטחה אל תדביק את הכותרת המתקבלת במסמך משותף, כרטיס או צ'אט, ואל תשלח אישור בסיסי על שום דבר מלבד HTTPS האסימון הוא הסיסמה. כי הכלי הזה מקודד בדפדפן שלך ולעולם לא מעלה שום דבר, יצירת האישור בטוחה; לאן זה הולך אחר כך עליך.
מתי עלי להשתמש ב-Basic auth, ומתי לא?
אישור בסיסי הוא לא הכלי המתאים לכל עבודה, ולדעת איפה הוא מתאים מרחיק אותך מצרות החוזק שלו הוא פשטות: לשיחות משרת לשרת, כלים פנימיים, רישום חבילות פרטיות, עבודות CI ו-webhooks שבהם שני הקצוות כבר סומכים אחד על השני והכל רץ על HTTPS, קשה לנצח אין מה לנהל משא ומתן, אין אסימון לרענן, וכל לקוח וספרייה של HTTP תומכים בזה מחוץ לקופסה כשאתה שולט בשני הצדדים והחיבור מוצפן, אישור בסיסי הוא בחירה סבירה לחלוטין שהמשיכה לעבוד במשך שלושים שנה.
החולשות שלו מופיעות ברגע שאתה יוצא מחוץ לתיבה הזו. מכיוון שהאישור נשלח בכל בקשה, שורת יומן אחת שדלפה או פרוקסי שמתעד כותרות חושף אותו לצמיתות, וסיבוב זה אומר לשנות אותו בכל מקום בבת אחת. אין לו מושג של היקף, אז אישור בסיסי הוא הכל או כלום: הוא לא יכול להעניק גישה לקריאה בלבד או לפוג לאחר שעה. והוא שם סיסמה אמיתית וארוכת חיים על החוט בכל שיחה, בעוד שסכימות מבוססות אסימונים מאפשרות לך לחלק במקום אישור קצר מועד בהיקף צר.
עבור אימות הפונה למשתמש, או בכל מקום שאתה צריך היקפים, תפוגה או ביטול, אסימון נושא הוא המודל הטוב יותר, וה- מפענח JWT האם הכלי הנלווה לבדיקת אלה כלל אצבע שימושי: להגיע ל-Basic auth עבור שיחות מכונה למכונה שאתה שולט בהן באופן מלא, ולהגיע לאסימונים כאשר מעורב צד שלישי, הפעלת דפדפן או גבול הרשאה הטבלה שלהלן מסכמת את המסחר.
| השתמש באישור בסיסי עבור | העדיפו אסימונים עבור |
|---|---|
| קריאות API משרת לשרת שאתה שולט בהן | הפעלות הפונות למשתמש |
| כלים פנימיים ורישום פרטי | גישה בהיקף או בקריאה בלבד |
| משרות CI ו-webhooks דרך HTTPS | אישורים שחייבים לפוג |
שאלות נפוצות
מהו אימות HTTP Basic? HTTP Basic Authentication היא סכימה שבה לקוח שולח שם משתמש וסיסמה עם כל בקשה בכותרת Authorization הערך הוא המילה Basic ואחריה קידוד base64 של שם משתמש: סיסמה היא מוגדרת ב-RFC 7617 והיא הדרך הפשוטה ביותר עבור שרת לבדוק אישורים.
כיצד בנויה כותרת האישור הבסיסית? הצטרף לשם המשתמש והסיסמה עם נקודתיים בודדת כדי ליצור שם משתמש: סיסמה, מקודד את המחרוזת הזו כ-UTF-8 בתים, base64-מקודד את הבתים, ומקדים את התוצאה עם Basic. הכותרת הסופית היא Authorization: Basic ואחריה האסימון הזה.
האם אימות בסיסי מאובטח? רק דרך HTTPS.Base64 הוא קידוד, לא הצפנה, כך שכל מי שיכול לקרוא את הכותרת יכול לפענח את הסיסמה באופן מיידי. אישור בסיסי אינו מספק סודיות בפני עצמו ויש לשלוח אותו תמיד דרך חיבור TLS כדי להיות בטוח.
האם שם המשתמש יכול להכיל נקודתיים? מס 'הנקודתיים הראשון מפריד את שם המשתמש מהסיסמה, כך נקודתיים בשם המשתמש יהיה misread as הגבול ולפצל את האישור במקום הלא נכון הסיסמה עשויה להכיל כל מספר של נקודתיים המחולל מזהיר אותך אם שם המשתמש יש אחד.
כיצד אוכל לפענח אסימון אישור בסיסי? קח את החלק base64 אחרי Basic, base64-פענח אותו, וקרא אותו כטקסט UTF-8 התוצאה היא שם משתמש: סיסמה, פיצול על נקודתיים הראשון. הדבק כל כותרת אישור בסיסית לתוך הכלי's לפענח מצב לעשות את זה באופן מיידי.
מה שווה ערך התלתלים? curl -u שם משתמש: סיסמה https://example.com עושה את אותו הדבר, כי curl בונה עבורך את הכותרת Authorization: Basic מהערך -u. הכלי מציג גם את הטופס הזה וגם את טופס הכותרת המפורש -H כך שתוכל להעתיק את המתאים.
האם הכלי הזה שולח את האישורים שלי לכל מקום? מס 'הקידוד והפענוח לרוץ לחלוטין בדפדפן שלך עם JavaScript.שם המשתמש והסיסמה שלך לעולם לא מועלים לשרת כלשהו, ולכן זה בטוח לשימוש עם אישורים אמיתיים, חיים.
מדוע להשתמש בקידוד UTF-8 עבור האישור? RFC 7617 ממליץ על UTF-8 כך ששמות משתמש וסיסמאות שאינם ASCII מקודדים באופן עקבי בין לקוח לשרת. מקודד שמניח ש-ASCII ישחית אותיות מודגשות או סקריפטים שאינם לטיניים, ומייצר אסימון שהשרת לא יכול להתאים.



