X-ThunderPhone-Signature. הגדירו את האימות פעם אחת והשתמשו באותו מסייע בכל מטפל.
האלגוריתם
- קראו את גוף הבקשה הגולמי — הבתים המדויקים ששלחנו אליכם ב-POST.
- חשבו את
hmac_sha256(secret, body).hexdigest(). - השוו בזמן קבוע מול
X-ThunderPhone-Signature. (השוואת מחרוזות נאיבית חושפת מידע על תזמון.)
, ו-: ללא רווחים), UTF-8. כך מתקבלת דרך שנייה ושקולה לחלוטין
כאשר המסגרת שלכם חושפת רק JSON מפוענח:
בצעו סריאליזציה קנונית מחדש וחשבו עליה HMAC.
איזה סוד?
אחסנו את הסוד במנהל הסודות או במשתנה הסביבה שלכם — לעולם אל תבצעו לו commit.
מימושי עזר
כל ארבעת המימושים מאמתים את גוף הבקשה הגולמי:חיבור ספציפי למסגרת עבודה
אימות קריאות לכלים
כאשר הסוכן מפעיל ישירות אחד מ- כלי הפונקציות שלכם (לכלי ישendpoint), הבקשה כוללת שתי כותרות של ThunderPhone לצד
endpoint.headers שהגדרתם:
X-ThunderPhone-Call-ID— המזהה המספרי של השיחה הפעילה.X-ThunderPhone-Signature— HMAC-SHA256, עם מפתח שהוא סוד ה-webhook ברמת הארגון, על פני הבתים המדויקים של גוף הבקשה.
verify() פועל ללא שינוי, עם שתי נקודות שחשוב לשים לב אליהן:
- לכלי
GET/DELETEאין גוף. הארגומנטים מועברים כפרמטרים של שאילתה, והחתימה מחושבת על פני מחרוזת בתים ריקה — לכן השתמשו ב-verify(b"", sig, secret)(Python) אוverify(Buffer.alloc(0), sig, secret)(Node). אל תבצעו גיבוב של מחרוזת השאילתה. - לארגונים ללא webhook מדור קודם מוגדר אין סוד ארגוני. במקרה זה,
קריאות לכלים כוללות רק את
X-ThunderPhone-Call-IDוללא כותרת חתימה. הגדירו את ה-webhook מדור קודם (PUT /v1/webhook) כדי לקבל סוד לחתימה, או אמתו קריאות לכלים באמצעות כותרת משלכם דרךendpoint.headers.
endpoint, המועברים
ל-webhook הארגוני שלכם כ-telephony.tool / web.tool) הוא webhook חתום
רגיל — ההנחיות הסטנדרטיות שלמעלה חלות. ראו
כלי פונקציות עבור שני מבני הבקשות.
מלכודות נפוצות
סריאליזציה מחדש עם עיצוב ברירת מחדל
סריאליזציה מחדש עם עיצוב ברירת מחדל
ניתוח הגוף וייצואו מחדש עם הגדרות ברירת המחדל של ספריית ה-JSON שלכם
(רווחים אחרי
, / :, מפתחות בסדר ההוספה) יוצר
בתים שונים ושובר את ה-HMAC. אמתו את הגוף הגולמי — או אם
אתם חייבים לבצע סריאליזציה מחדש, התאימו בדיוק לצורה הקנונית שלנו: מפתחות
ממוינים, מפרידים קומפקטיים, UTF-8.המסגרת מנתחת JSON אוטומטית
המסגרת מנתחת JSON אוטומטית
תוכנת התווך
express.json() של Express צורכת את זרם הגוף
ואתם מאבדים את הבתים הגולמיים. השתמשו ב-express.raw() במיוחד בנתיב
ה-webhook, או אחסנו את הגוף הגולמי במאגר בתוכנת תווך מוקדמת.
אותו הדבר נכון לגבי NestJS / Koa — עיינו בתיעוד שלהם בנושא “raw body”.השוואה שאינה בטוחה מבחינת תזמון
השוואה שאינה בטוחה מבחינת תזמון
expected === signature ב-JS או expected == signature ב-
Python הן השוואות שזמן הביצוע שלהן משתנה. השתמשו ב-crypto.timingSafeEqual
או ב-hmac.compare_digest בהתאמה. ההבדל בביצועים
זניח.סוד שגוי עבור נקודות קצה של כלים
סוד שגוי עבור נקודות קצה של כלים
קריאות ישירות לנקודות קצה של כלים נחתמות באמצעות סוד ה-webhook
ברמת הארגון (
GET /v1/webhook) — ולא באמצעות סוד ספציפי לנקודת קצה
מתוך /v1/developer/webhook-endpoints. השתמשו מחדש באותה פונקציית verify(),
אך ודאו שאתם מעבירים לה את סוד הארגון בנתיבי כלים.גיבוב מחרוזת השאילתה בכלי GET/DELETE
גיבוב מחרוזת השאילתה בכלי GET/DELETE
עבור שיטות כלים ללא גוף, החתימה מכסה את מחרוזת הבתים הריקה,
וכך נשמר מתכון אוניברסלי אחד: הפעילו HMAC על גוף הבקשה הגולמי,
יהיה אשר יהיה. גיבוב ה-URL או מחרוזת השאילתה לעולם לא יתאים.
אי-החזרת 401 במקרה של אי-התאמה
אי-החזרת 401 במקרה של אי-התאמה
החזרת 200 כאשר האימות נכשל הופכת את המטפל ליעד להתקפת שידור חוזר.
החזירו תמיד תגובה שאינה 2xx אם האימות נכשל.
השלבים הבאים
סקירת webhooks
סמנטיקת מסירה, ניסיונות חוזרים, כתובות IP של המקור.
נקודות קצה של webhook
נהלו כמה כתובות URL, החליפו סודות.
כלי פונקציות
שני נתיבי הפעלת הכלים ומבני הבקשות שלהם.
שילובי כלים
בנו שילוב מלא המבוסס על כלים מקצה לקצה.