הטמעה ללא קובצי Cookie

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

איך פועל הטמעה ללא קובצי Cookie?

כשקובצי Cookie של צד שלישי לא חסומים, נוצר קובץ Cookie זמני כשמשתמש מתחבר ל-Looker בפעם הראשונה. קובץ ה-Cookie הזה נשלח עם כל בקשת משתמש, ושרת Looker משתמש בו כדי לקבוע את זהות המשתמש שיזם את הבקשה. כשקובצי Cookie חסומים, קובץ ה-Cookie לא נשלח עם הבקשה, ולכן שרת Looker לא יכול לזהות את המשתמש שמשויך לבקשה.

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

כדי להשתמש באחד מממשקי ה-API, אפליקציית ההטמעה צריכה להיות מסוגלת לבצע אימות ב-Looker API עם הרשאות אדמין. הדומיין של ההטמעה צריך להופיע ברשימת ההיתרים של דומיינים להטמעה, או שאם משתמשים ב-Looker 23.8 ואילך, אפשר לכלול את הדומיין של ההטמעה כשמשיגים סשן ללא קובצי Cookie.

יצירת iframe להטמעה של Looker

בתרשים הרצף הבא מוצג תהליך היצירה של iframe להטמעה. יכול להיות שייווצרו כמה רכיבי iframe בו-זמנית או בשלב מסוים בעתיד. אם מטמיעים את ה-iframe בצורה נכונה, הוא יצטרף אוטומטית לסשן שנוצר על ידי ה-iframe הראשון. ‫Looker Embed SDK מפשט את התהליך הזה על ידי הצטרפות אוטומטית להפעלה הקיימת.

תרשים רצף שממחיש את היצירה של iframe להטמעה.

  1. המשתמש מבצע פעולה באפליקציה להטמעה שגורמת ליצירת iframe של Looker.
  2. לקוח האפליקציה להטמעה מקבל סשן ב-Looker. אפשר להשתמש ב-Looker Embed SDK כדי ליזום את הסשן הזה, אבל צריך לספק כתובת URL של נקודת קצה או פונקציית קריאה חוזרת. אם משתמשים בפונקציית קריאה חוזרת, היא תקרא לשרת של אפליקציית ההטמעה כדי לקבל את סשן ההטמעה של Looker. אחרת, Embed SDK יקרא לכתובת ה-URL של נקודת הקצה שצוינה.
  3. שרת האפליקציה להטמעה משתמש ב-Looker API כדי לקבל סשן הטמעה. הקריאה הזו ל-API דומה לתהליך החתימה של הטמעה חתומה ב-Looker, כי היא מקבלת את הגדרת המשתמש של ההטמעה כקלט. אם כבר קיים סשן של הטמעה של Looker עבור המשתמש המתקשר, צריך לכלול בשיחה את אסימון ההפניה של הסשן המשויך. הנושא הזה מוסבר בפירוט רב יותר בקטע השגת סשן במאמר הזה.
  4. העיבוד של נקודת הקצה של הסשן להטמעה של קבלת גישה דומה לעיבוד של נקודת הקצה החתומה /login/embed/(signed url), בכך שהיא מצפה להגדרת משתמש Looker להטמעה כגוף הבקשה, ולא בכתובת ה-URL. תהליך נקודת הקצה של הסשן להטמעה מאמת, ואז יוצר או מעדכן את המשתמש המוטמע. הוא יכול גם לקבל טוקן הפניה לסשן קיים. זה חשוב כי זה מאפשר לכמה מסגרות iframe מוטמעות של Looker לשתף את אותו סשן. המשתמש שמוטמע לא יעודכן אם מסופק אסימון הפניה לסשן והסשן לא פג. התמיכה הזו מתאימה לתרחיש השימוש שבו נוצר iframe אחד באמצעות כתובת URL חתומה להטמעה, ונוצרים עוד iframes בלי כתובת URL חתומה להטמעה. במקרה כזה, קובץ ה-Cookie יועבר ל-iframes בלי כתובות URL מוטמעות חתומות מהסשן הראשון.
  5. הקריאה ל-Looker API מחזירה ארבעה טוקנים, שלכל אחד מהם יש אורך חיים (TTL):
    • טוקן הרשאה (TTL = 30 שניות)
    • טוקן ניווט (TTL = 10 דקות)
    • טוקן API (אורך חיים = 10 דקות)
    • טוקן הפניה לסשן (TTL = משך החיים שנותר של הסשן)
  6. שרת האפליקציה להטמעה צריך לעקוב אחרי הנתונים שמוחזרים מנתוני Looker ולשייך אותם גם למשתמש שקורא לפונקציה וגם לסוכן המשתמש של הדפדפן של המשתמש שקורא לפונקציה. הצעות לאופן הביצוע מופיעות בקטע יצירת טוקנים במסמך הזה. הקריאה הזו תחזיר את טוקן ההרשאה, טוקן הניווט וטוקן ה-API, יחד עם כל ערכי ה-TTL המשויכים. אסימון ההפניה של הסשן צריך להיות מאובטח ולא להיחשף בדפדפן שממנו מתבצעת הקריאה.
  7. אחרי שהאסימונים מוחזרים לדפדפן, צריך ליצור כתובת URL לכניסה להטמעה של Looker. ה-Looker Embed SDK ייצור באופן אוטומטי את כתובת ה-URL להתחברות להטמעה. כדי להשתמש ב-windows.postMessage API כדי ליצור את כתובת ה-URL של ההטמעה להתחברות, אפשר לעיין בדוגמאות שבקטע שימוש ב-Looker windows.postMessage API במסמך הזה.

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

  8. נקודת הקצה של הכניסה להטמעה ב-Looker קובעת אם הכניסה היא להטמעה ללא קובצי Cookie, שמסומנת בנוכחות של אסימון ההרשאה. אם אסימון ההרשאה תקין, המערכת בודקת את הדברים הבאים:

    • הסשן המשויך עדיין תקף.
    • המשתמש המשובץ המשויך עדיין תקף.
    • סוכן המשתמש של הדפדפן שמשויך לבקשה זהה לסוכן הדפדפן שמשויך לסשן.
  9. אם הבדיקות מהשלב הקודם עוברות בהצלחה, הבקשה מופנית מחדש באמצעות ה-URI של היעד שמופיע בכתובת ה-URL. זהו אותו תהליך כמו בכניסה להטמעה חתומה ב-Looker.

  10. הבקשה הזו היא ההפניה להפעלת לוח הבקרה של Looker. הבקשה הזו תכלול את טוקן הניווט כפרמטר.

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

    • הסשן המשויך עדיין תקף.
    • סוכן המשתמש של הדפדפן שמשויך לבקשה זהה לסוכן הדפדפן שמשויך לסשן.

    אם הוא תקף, הסשן ישוחזר עבור הבקשה והבקשה של לוח הבקרה תופעל.

  12. קוד ה-HTML לטעינת מרכז הבקרה מוחזר ל-iframe.

  13. ממשק המשתמש של Looker שפועל ב-iframe קובע ש-HTML של לוח הבקרה הוא תגובת הטמעה ללא קובצי Cookie. בשלב הזה, ממשק המשתמש של Looker שולח הודעה לאפליקציה להטמעה כדי לבקש את הטוקנים שאוחזרו בשלב 6. ממשק המשתמש מחכה עד שהוא מקבל את האסימונים. אם האסימונים לא מגיעים, מוצגת הודעה.

  14. אפליקציית ההטמעה שולחת את הטוקנים ל-iframe המוטמע של Looker.

  15. כשהאסימונים מתקבלים, ממשק המשתמש של Looker שפועל ב-iframe מתחיל את התהליך של עיבוד אובייקט הבקשה. במהלך התהליך הזה, ממשק המשתמש יבצע קריאות ל-API לשרת Looker. טוקן ה-API שהתקבל בשלב 15 מוזרק אוטומטית ככותרת לכל בקשות ה-API.

  16. לפני שמופעלת נקודת קצה כלשהי, שרת Looker מחפש את טוקן ה-API בבקשה. אם השרת מוצא את הטוקן, הוא בודק את הדברים הבאים:

    • הסשן המשויך עדיין תקף.
    • סוכן המשתמש של הדפדפן שמשויך לבקשה זהה לסוכן הדפדפן שמשויך לסשן.

    אם הסשן תקין, הוא משוחזר עבור הבקשה, ובקשת ה-API מופעלת.

  17. הנתונים בלוח הבקרה יוחזרו.

  18. לוח הבקרה מוצג.

  19. למשתמש יש שליטה בלוח הבקרה.

יצירת טוקנים חדשים

תרשים הרצף הבא מדגים את יצירת האסימונים החדשים.

דיאגרמת רצף שממחישה יצירה של טוקנים חדשים.

  1. ממשק המשתמש של Looker שפועל ב-iframe המוטמע עוקב אחרי ה-TTL של אסימוני ההטמעה.
  2. כשהתוקף של הטוקנים מתקרב לסיום, ממשק המשתמש של Looker שולח הודעת רענון טוקן ללקוח של אפליקציית ההטמעה.
  3. לאחר מכן, הלקוח של האפליקציה להטמעה מבקש טוקנים חדשים מנקודת קצה שמוטמעת בשרת של האפליקציה להטמעה. ‫Looker Embed SDK יבקש באופן אוטומטי טוקנים חדשים, אבל צריך לספק את כתובת ה-URL של נקודת הקצה או פונקציית קריאה חוזרת. אם משתמשים בפונקציית הקריאה החוזרת, היא תקרא לשרת של אפליקציית ההטמעה כדי ליצור אסימונים חדשים. אחרת, Embed SDK יקרא לכתובת ה-URL של נקודת הקצה שצוינה.
  4. האפליקציה להטמעה מוצאת את session_reference_token שמשויך לסשן ההטמעה. בדוגמה שמופיעה במאגר Git של Looker Embed SDK נעשה שימוש בקובצי Cookie של סשן, אבל אפשר להשתמש גם במטמון מבוזר בצד השרת, כמו Redis.
  5. שרת האפליקציה להטמעה קורא לשרת Looker עם בקשה ליצירת אסימונים. בנוסף לסוכן המשתמש של הדפדפן שיזם את הבקשה, הבקשה הזו דורשת גם טוקנים עדכניים של API וניווט.
  6. שרת Looker מאמת את סוכן המשתמש, את אסימון ההפניה של הסשן, את אסימון הניווט ואת אסימון ה-API. אם הבקשה תקפה, נוצרים טוקנים חדשים.
  7. האסימונים מוחזרים לשרת של אפליקציית ההטמעה שקוראת ל-API.
  8. שרת האפליקציה להטמעה מסיר את טוקן ההפניה של הסשן מהתגובה ומחזיר את התגובה שנותרה ללקוח של האפליקציה להטמעה.
  9. הלקוח של אפליקציית ההטמעה שולח את האסימונים שנוצרו אל ממשק המשתמש של Looker. ה-SDK להטמעה של Looker יעשה את זה באופן אוטומטי. לקוחות של אפליקציות מוטמעות שמשתמשים ב-windows.postMessage API יהיו אחראים לשליחת האסימונים. אחרי שממשק המשתמש של Looker מקבל את האסימונים, הוא משתמש בהם בקריאות הבאות ל-API ובניווטים בדפים.

הטמעה של Looker ללא קובצי Cookie

אפשר להטמיע הטמעה של Looker ללא קובצי Cookie באמצעות Looker Embed SDK או windows.postMessage API. אפשר להשתמש בשיטה Looker Embed SDK, אבל יש גם דוגמה שמראה איך להשתמש ב-API‏ windows.postMessage. הסברים מפורטים על שתי ההטמעות זמינים בקובץ ה-README של Looker Embed SDK. מאגר ה-git של Embed SDK מכיל גם הטמעות פעילות.

הגדרת מופע Looker

הטמעה ללא קובצי Cookie חולקת מאפיינים עם הטמעה חתומה ב-Looker.

דרישות מוקדמות

כדי להשתמש בהטמעה ללא קובצי Cookie ולחשוף את נקודות הקצה של ה-API להטמעה ללא קובצי Cookie, אדמין ב-Looker צריך לאמת ולהפעיל את הדרישות הבאות בחלונית Admin ב-Looker:

  • הטמעת אימות SSO: בחלונית Admin > Platform > Embed, מפעילים את האפשרות Embed SSO Authentication. הטמעה ללא קובצי Cookie מסתמכת על הפונקציה הבסיסית Embed SSO Authentication (הטמעה של אימות SSO) כהגדרה בסיסית.
  • סשנים מתמשכים: בחלונית Admin > Authentication > Sessions (אדמין > אימות > סשנים), מפעילים את האפשרות סשנים מתמשכים.
  • הרשאות משתמש ב-API: מוודאים שאמצעי האימות של ה-API שמשמשים להשגת הטוקן שייכים למשתמש Looker עם התפקיד אדמין או עם תפקיד בהתאמה אישית שכולל את ההרשאה manage_embed_settings.

הגדרת הסוד של אסימון ה-JSON Web Token

בניגוד להטמעה עם חתימה ב-Looker, הטמעה ללא קובצי Cookie לא משתמשת בהגדרה Embed Secret. הטמעה ללא קובצי Cookie משתמשת ב-JSON Web Token‏ (JWT) בצורה של הגדרה Embed JWT Secret, שאפשר להגדיר או לאפס בדף Embed בקטע Platform בתפריט Admin.

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

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

הטמעה של לקוח אפליקציה

בקטע הזה יש דוגמאות להטמעה של הטמעה ללא קובצי Cookie בלקוח של האפליקציה, והוא כולל את קטעי המשנה הבאים:

התקנה או עדכון של Looker Embed SDK

כדי להשתמש בהטמעה ללא קובצי Cookie, צריך להשתמש בגרסאות הבאות של Looker SDK:

@looker/embed-sdk >= 2.0.0
@looker/sdk >= 22.16.0

שימוש ב-Looker Embed SDK

נוספה שיטת אתחול חדשה ל-Embed SDK כדי להתחיל את הסשן ללא קובצי Cookie. השיטה הזו מקבלת שתי מחרוזות של כתובות URL או שתי פונקציות קריאה חוזרת. מחרוזות כתובות ה-URL צריכות להפנות לנקודות קצה בשרת של האפליקציה שבה מתבצעת ההטמעה. פרטי ההטמעה של נקודות הקצה האלה בשרת האפליקציות מפורטים בקטע הטמעה של שרת האפליקציות במסמך הזה.

getEmbedSDK().initCookieless(
  runtimeConfig.lookerHost,
  '/acquire-embed-session',
  '/generate-embed-tokens'
)

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

const acquireEmbedSessionCallback =
  async (): Promise<LookerEmbedCookielessSessionData> => {
    const resp = await fetch('/acquire-embed-session')
    if (!resp.ok) {
      console.error('acquire-embed-session failed', { resp })
      throw new Error(
        `acquire-embed-session failed: ${resp.status} ${resp.statusText}`
      )
    }
    return (await resp.json()) as LookerEmbedCookielessSessionData
  }

const generateEmbedTokensCallback =
  async ({ api_token, navigation_token }): Promise<LookerEmbedCookielessSessionData> => {
    const resp = await fetch('/generate-embed-tokens', {
      method: 'PUT',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ api_token, navigation_token }),
    })
    if (!resp.ok) {
      console.error('generate-embed-tokens failed', { resp })
      throw new Error(
        `generate-embed-tokens failed: ${resp.status} ${resp.statusText}`
      )
    }
    return (await resp.json()) as LookerEmbedCookielessSessionData
  }

getEmbedSDK().initCookieless(
  runtimeConfig.lookerHost,
  acquireEmbedSessionCallback,
  generateEmbedTokensCallback
)

שימוש ב-Looker windows.postMessage API

אפשר לראות דוגמה מפורטת לשימוש ב-API של windows.postMessage בקבצים message_example.ts ו-message_utils.ts במאגר ה-Git של Embed SDK. כאן מפורטים הדגשים של הדוגמה.

בדוגמה הבאה מוסבר איך ליצור את כתובת ה-URL של ה-iframe. פונקציית הקריאה החוזרת זהה לדוגמה acquireEmbedSessionCallback שראינו קודם.

  private async getCookielessLoginUrl(): Promise<string> {
    const { authentication_token, navigation_token } =
      await this.embedEnvironment.acquireSession()
    const url = this.embedUrl.startsWith('/embed')
      ? this.embedUrl
      : `/embed${this.embedUrl}`
    const embedUrl = new URL(url, this.frameOrigin)
    if (!embedUrl.searchParams.has('embed_domain')) {
      embedUrl.searchParams.set('embed_domain', window.location.origin)
    }
    embedUrl.searchParams.set('embed_navigation_token', navigation_token)
    const targetUri = encodeURIComponent(
      `${embedUrl.pathname}${embedUrl.search}${embedUrl.hash}`
    )
    return `${embedUrl.origin}/login/embed/${targetUri}?embed_authentication_token=${authentication_token}`
  }

בדוגמה הבאה אפשר לראות איך להאזין לבקשות לאסימונים, ליצור אסימונים חדשים ולשלוח אותם ל-Looker. פונקציית הקריאה החוזרת זהה לדוגמה הקודמת generateEmbedTokensCallback.

      this.on(
        'session:tokens:request',
        this.sessionTokensRequestHandler.bind(this)
      )

  private connected = false

  private async sessionTokensRequestHandler(_data: any) {
    const contentWindow = this.getContentWindow()
    if (contentWindow) {
      if (!this.connected) {
        // When not connected the newly acquired tokens can be used.
        const sessionTokens = this.embedEnvironment.applicationTokens
        if (sessionTokens) {
          this.connected = true
          this.send('session:tokens', this.embedEnvironment.applicationTokens)
        }
      } else {
        // If connected, the embedded Looker application has decided that
        // it needs new tokens. Generate new tokens.
        const sessionTokens = await this.embedEnvironment.generateTokens()
        this.send('session:tokens', sessionTokens)
      }
    }
  }

  send(messageType: string, data: any = {}) {
    const contentWindow = this.getContentWindow()
    if (contentWindow) {
      const message: any = {
        type: messageType,
        ...data,
      }
      contentWindow.postMessage(JSON.stringify(message), this.frameOrigin)
    }
    return this
  }

הטמעה של שרת אפליקציות

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

הטמעה בסיסית

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

  1. קבלת סשן – אם כבר קיים אסימון הפניה לסשן והוא עדיין פעיל, בקשות לסשן יצטרפו לסשן הקיים. הפונקציה acquire session מופעלת כשנוצר iframe.
  2. יצירת טוקנים – Looker מפעיל מעת לעת קריאות לנקודת הקצה הזו.

צירוף סשנים

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

  app.get(
    '/acquire-embed-session',
    async function (req: Request, res: Response) {
      try {
        const current_session_reference_token =
          req.session && req.session.session_reference_token
        const response = await acquireEmbedSession(
          req.headers['user-agent']!,
          user,
          current_session_reference_token
        )
        const {
          authentication_token,
          authentication_token_ttl,
          navigation_token,
          navigation_token_ttl,
          session_reference_token,
          session_reference_token_ttl,
          api_token,
          api_token_ttl,
        } = response
        req.session!.session_reference_token = session_reference_token
        res.json({
          api_token,
          api_token_ttl,
          authentication_token,
          authentication_token_ttl,
          navigation_token,
          navigation_token_ttl,
          session_reference_token_ttl,
        })
      } catch (err: any) {
        res.status(400).send({ message: err.message })
      }
    }
  )

async function acquireEmbedSession(
  userAgent: string,
  user: LookerEmbedUser,
  session_reference_token: string
) {
  await acquireLookerSession()
    try {
    const request = {
      ...user,
      session_reference_token: session_reference_token,
    }
    const sdk = new Looker40SDK(lookerSession)
    const response = await sdk.ok(
      sdk.acquire_embed_cookieless_session(request, {
        headers: {
          'User-Agent': userAgent,
        },
      })
    )
    return response
  } catch (error) {
    console.error('embed session acquire failed', { error })
    throw error
  }
}

החל מ-Looker 23.8, אפשר לכלול את הדומיין של ההטמעה כשמשיגים את הסשן ללא קובצי Cookie. זוהי דרך חלופית להוספת הדומיין להטמעה באמצעות החלונית Admin > Embed ב-Looker. ‫Looker שומר את הדומיין של ההטמעה במסד הנתונים הפנימי של Looker, ולכן הוא לא יוצג בחלונית ניהול > הטמעה. במקום זאת, דומיין ההטמעה משויך לסשן ללא קובצי Cookie וקיים רק למשך הסשן. אם אתם רוצים להשתמש בתכונה הזו, כדאי לעיין בשיטות המומלצות לשיפור האבטחה.

יצירת טוקנים

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

חשוב לדעת איך לטפל בתשובות 400, שמתרחשות כשהאסימונים לא תקינים. למרות שלא אמורה להיות תגובה 400, אם היא מתקבלת, מומלץ לסיים את סשן ההטמעה של Looker. כדי לסיים את סשן ההטמעה של Looker, אפשר להרוס את ה-iframe של ההטמעה או להגדיר את הערך session_reference_token_ttl לאפס בהודעה session:tokens. אם מגדירים את הערך session_reference_token_ttl לאפס, ב-iframe של Looker מוצגת תיבת דו-שיח של סשן שהסתיים.

תגובה מסוג 400 לא מוחזרת כשפג תוקף הסשן של ההטמעה. אם תוקף ההטמעה פג, מוחזרת תשובה עם קוד 200 והערך session_reference_token_ttl מוגדר לאפס.

  app.put(
    '/generate-embed-tokens',
    async function (req: Request, res: Response) {
      try {
        const session_reference_token = req.session!.session_reference_token
        const { api_token, navigation_token } = req.body as any
        const tokens = await generateEmbedTokens(
          req.headers['user-agent']!,
          session_reference_token,
          api_token,
          navigation_token
        )
        res.json(tokens)
      } catch (err: any) {
        res.status(400).send({ message: err.message })
      }
    }
  )
}
async function generateEmbedTokens(
  userAgent: string,
  session_reference_token: string,
  api_token: string,
  navigation_token: string
) {
  if (!session_reference_token) {
    console.error('embed session generate tokens failed')
    // missing session reference  treat as expired session
    return {
      session_reference_token_ttl: 0,
    }
  }
  await acquireLookerSession()
  try {
    const sdk = new Looker40SDK(lookerSession)
    const response = await sdk.ok(
      sdk.generate_tokens_for_cookieless_session(
        {
          api_token,
          navigation_token,
          session_reference_token: session_reference_token || '',
        },
        {
          headers: {
            'User-Agent': userAgent,
          },
        }
      )
    )
    return {
      api_token: response.api_token,
      api_token_ttl: response.api_token_ttl,
      navigation_token: response.navigation_token,
      navigation_token_ttl: response.navigation_token_ttl,
      session_reference_token_ttl: response.session_reference_token_ttl,
    }
  } catch (error: any) {
    if (error.message?.includes('Invalid input tokens provided')) {
      // The Looker UI does not know how to handle bad
      // tokens. This shouldn't happen but if it does expire the
      // session. If the token is bad there is not much that that
      // the Looker UI can do.
      return {
        session_reference_token_ttl: 0,
      }
    }
    console.error('embed session generate tokens failed', { error })
    throw error
  }

שיקולים להטמעה

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

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

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

כשפג התוקף של סשן ההטמעה של Looker, מוצגת תיבת דו-שיח ב-iframe המוטמע. בשלב הזה, המשתמש לא יוכל לעשות שום דבר במופע המוטמע. במקרה כזה, ייווצרו session:status אירועים, שיאפשרו לאפליקציה להטמעה לזהות את המצב הנוכחי של אפליקציית Looker המוטמעת ולבצע פעולה כלשהי.

אפליקציית הטמעה יכולה לזהות אם תוקף הסשן של ההטמעה פג על ידי בדיקה אם הערך session_reference_token_ttl שמוחזר על ידי נקודת הקצה generate_tokens הוא אפס. אם הערך הוא אפס, סימן שהתוקף של הסשן של ההטמעה פג. מומלץ להשתמש בפונקציית קריאה חוזרת ליצירת טוקנים כשמטמיעים את הדוח ללא קובצי Cookie. לאחר מכן, פונקציית הקריאה החוזרת יכולה לקבוע אם תוקף הסשן של ההטמעה פג, ולהרוס את ה-iframe המוטמע כחלופה לשימוש בתיבת הדו-שיח המוגדרת כברירת מחדל לגבי סשן מוטמע שתוקפו פג.

הרצת הדוגמה להטמעה ב-Looker ללא קובצי Cookie

מאגר ה-SDK להטמעה מכיל שרת ולקוח של Node Express שנכתבו ב-TypeScript ומיישמים אפליקציית הטמעה. הדוגמאות שמוצגות למעלה לקוחות מההטמעה הזו. ההנחיות הבאות מניחות שמופע Looker שלכם הוגדר לשימוש בהטמעה ללא קובצי Cookie, כפי שמתואר בהמשך.

אפשר להריץ את השרת באופן הבא:

  1. משכפלים את מאגר Embed SDK‏ – git clone git@github.com:looker-open-source/embed-sdk.git
  2. שינוי הספרייה – cd embed-sdk
  3. מתקינים את יחסי התלות – npm install
  4. מגדירים את השרת, כמו שמוסבר בקטע הגדרת השרת במאמר הזה.
  5. מריצים את השרת — npm run server

הגדרת השרת

יוצרים קובץ .env בבסיס של המאגר המשוכפל (הקובץ הזה כלול ב-.gitignore).

הפורמט הוא כזה:

LOOKER_WEB_URL=your-looker-instance-url.com
LOOKER_API_URL=https://your-looker-instance-url.com
LOOKER_DEMO_HOST=localhost
LOOKER_DEMO_PORT=8080
LOOKER_EMBED_SECRET=embed-secret-from-embed-admin-page
LOOKER_CLIENT_ID=client-id-from-user-admin-page
LOOKER_CLIENT_SECRET=client-secret-from-user-admin-page
LOOKER_DASHBOARD_ID=id-of-dashboard
LOOKER_LOOK_ID=id-of-look
LOOKER_EXPLORE_ID=id-of-explore
LOOKER_EXTENSION_ID=id-of-extension
LOOKER_VERIFY_SSL=true
LOOKER_REPORT_ID=id-of-report
LOOKER_QUERY_VISUALIZATION_ID=id-of-query-visualization

כשמשתמשים בהטמעה ב-Looker ללא קובצי Cookie, משתמשים שמנסים לפתוח קישורים בכרטיסייה חדשה או בחלון חדש בדפדפן (למשל, ניתוח מעמיק של לוחות בקרה, ניתוח נתונים או הורדות של מסמכים) עלולים להיתקל בשגיאה HTTP 401 Unauthorized או להיות מופנים לדף הכניסה של Looker. הבעיה הזו מתרחשת בדרך כלל כשקובצי Cookie של צד שלישי מושבתים בדפדפן.

מטרה

כדי למנוע נקודות חולשה שמאפשרות חטיפת סשנים, הוספנו ל-Looker (גרסאות 25.18.61 ומעלה, 25.20.44 ומעלה ו-26.0.22 ומעלה) תיקון אבטחה שמפסיק בכוונה להחזיר קובצי Cookie של סשנים בתגובה הראשונית להטמעה ללא קובצי Cookie. מכיוון שהדפדפן כבר לא מקבל את קובץ ה-cookie הזמני הזה של הסשן, פתיחה של כתובת URL של Looker בכרטיסייה או בחלון חדשים גורמת לאיבוד של הקשר האימות, ולכן הבקשה נכשלת.

פתרון ופתרונות עקיפים

  • שדרוג Looker: שדרוג מופע Looker לגרסה 26.0.36 ואילך. בגרסה הזו הוספנו תיקון שמוסיף באופן מאובטח טוקן חד-פעמי לכתובות URL שנפתחות בחלון חדש במהלך הפעלת הטמעה ללא קובצי Cookie. כך המשתמשים יכולים שוב לפתוח קישורים מאובטחים בכרטיסיות חדשות.
  • פתיחת קישורים באותו iframe: אם אי אפשר לשדרג באופן מיידי, צריך להגדיר את כל הקישורים בלוחות הבקרה המוטמעים כך שייפתחו באותו iframe. לשם כך, מגדירים את יעדי הקישורים ל-_self (לדוגמה, target="_self").
  • ניתוב דרך אפליקציית המארח: אם יש צורך לפתוח את הקישור בכרטיסייה או בחלון חדשים, צריך להגדיר את הקישור לדף חדש באפליקציית המארח שמפעיל iframe חדש להטמעה ללא קובצי Cookie, במקום לקשר ישירות למופע Looker.
  • שימוש בהטמעה חתומה עם דומיין מותאם אישית: לחלופין, אפשר להשתמש בהטמעה חתומה רגילה עם דומיין מותאם אישית.