為嵌入式 Looker 內容實作列層級區隔

作者:資深資料分析師 Christopher Seymour 和開發人員關係工程師 Dean Hicks

透過資料列層級區隔,您可以根據一或多個資料庫欄位中儲存的值,限制個別使用者可存取的資料。本指南說明在嵌入式 Looker 內容中實作資料列層級區隔的方法,內容涵蓋下列章節:

簡介

Looker 的嵌入功能是 Looker 產品最強大且最有價值的特色之一。如果您正在閱讀本指南,很可能已將 Looker 內容嵌入應用程式,或打算在不久的將來這麼做。

本指南旨在協助您進一步瞭解 Looker 嵌入功能的設計,以及如何在應用程式中導入區隔,讓合作夥伴管理多個品牌的存取權。由於內容深入探討這個主題,因此篇幅較長。請注意,本指南並非針對簡單問題的快速解決方案,而是協助您更妥善管理整個 Looker 嵌入式用途的基礎。

用途總覽

本指南說明常見的用途,也就是貴公司在產品中嵌入 Looker 內容,並為應查看不同資料切片的使用者區隔提供服務。

在這個簽署嵌入的用途中,假設您是 Looker 執行個體的管理員。您與兩種類型的外部嵌入使用者合作:客戶 (只能存取與特定品牌相關的資料) 和合作夥伴 (可存取多個品牌的資料)。 您有一個資訊主頁,其中包含幾個圖塊,會向使用您產品的每位客戶顯示,但您需要為每位客戶自動篩選資訊主頁,讓資訊主頁只顯示該客戶專屬的資料。本文範例使用兩個虛構公司:HooliPied Piper

您有一個名為「products」的資料表,其中顯示不同品牌的產品指標。每個品牌對應至已簽署的嵌入式應用程式中不同的嵌入式使用者 (具有不同的 external_user_id)。由於每個嵌入式使用者只能查看自己品牌的資料,因此您有一個 Explore,會對「brand」使用者屬性套用存取權篩選器:

explore: products {
  access_filter: {
    field: products.brand
    user_attribute: brand
  }
}

您有一個以這項探索為基礎的資訊主頁,其中有兩個圖塊:一個顯示品牌名稱,另一個顯示該品牌的產品數量。

您可以使用 create_sso_embed_url 端點,為每個嵌入使用者產生這個資訊主頁的嵌入網址。這個範例使用兩個品牌:Pied Piper 和 Hooli。以下是您在 Pied Piper 的 create_sso_embed_url 呼叫中使用的要求主體,其中 external_user_idpied_piper

{
  "target_url": "https://mylookerinstance.cloud.looker.com/embed/dashboards/17",
  "session_length": 300,
  "force_logout_login": true,
  "external_user_id": "pied_piper",
  "first_name": "PiedPiper",
  "last_name": "User",
  "permissions": ["access_data","see_user_dashboards"],
  "models": ["thelook"],
  "user_attributes": {"brand":"Pied Piper"}
}

為 Pied Piper 產生的網址會以這種方式顯示資訊主頁:

以下是 Hooli 的 create_sso_embed_url 呼叫所用的要求主體,其中 external_user_idhooli

{
  "target_url": "https://mylookerinstance.cloud.looker.com/embed/dashboards/17",
  "session_length": 300,
  "force_logout_login": true,
  "external_user_id": "hooli",
  "first_name": "Hooli",
  "last_name": "User",
  "permissions": ["access_data","see_user_dashboards"],
  "models": ["thelook"],
  "user_attributes": {"brand":"Hooli"}
}

為 Hooli 產生的網址會以這種方式顯示資訊主頁:

完成!系統會根據每個嵌入使用者的「品牌」使用者屬性值,篩選資訊主頁。

深入瞭解

太棒了!但如果我想讓單一使用者存取多個品牌,該怎麼做?如何確保只有相關使用者能查看我的資料?

好消息!Looker 的簽署嵌入功能旨在協助開發人員為使用者打造強大的專屬資料體驗,同時確保資料模型和內容存取權政策定義的資料治理機制維持不變。

確保資料治理滴水不漏,是提供強大資料體驗的關鍵。請繼續閱讀,瞭解一些概念和最佳做法,設計最適合您的體驗。首先,我們將簡要說明這些概念和做法的運作方式。

Looker 簽署嵌入的基本概念

請務必注意,嵌入環境中的 Looker 使用者驗證和管理機制,與非嵌入環境中的機制基本相同,也與大多數其他網路應用程式的機制基本相同。

在 Looker 簽署嵌入內容的環境中,由於簽署驗證步驟、使用者設定和資訊主頁本身都合併為一個複雜的長網址,因此可能會造成混淆。不過,該網址是用來建立工作階段,即使網址縮短後仍適用。請牢記這個概念,這對您打造優質資料體驗大有幫助。

已簽署嵌入網址結構

以下是 create_sso_embed_url 呼叫為 Pied Piper 產生的一個已簽署嵌入驗證網址 (附要求主體):

https://mylookerinstance.cloud.looker.com/login/embed/%2Fembed%2Fdashboards%2F17?permissions=%5B%22access_data%22%2C%22see_user_dashboards%22%5D&models=%5B%22thelook%22%5D&signature=iG6vcKBgnA50jaL2iShFeQHwFPN7wvTx7Rz6r%2FtFuvE%3D&nonce=%22967729518a7dbb8a178f1c03a3511dd1%22&time=1696013242&session_length=300&external_user_id=%22pied_piper%22&access_filters=%7B%7D&first_name=%22Pied%22&last_name=%22Piper%22&user_attributes=%7B%22brand%22%3A%22Pied+Piper%22%7D&force_logout_login=true

以下是解碼後的相同網址,並分成個別行:

https://mylookerinstance.cloud.looker.com/login/embed/
/embed/dashboards/17
?permissions=["access_data","see_user_dashboards"]
&models=["thelook"]
&signature=iG6vcKBgnA50jaL2iShFeQHwFPN7wvTx7Rz6r/tFuvE=
&nonce="967729518a7dbb8a178f1c03a3511dd1"
&time=1696013242
&session_length=300
&external_user_id="pied_piper"
&access_filters={}
&first_name="PiedPiper"
&last_name="User"
&user_attributes={"brand":"Pied Piper"}
&force_logout_login=true

存取這個網址時,會發生以下幾種情況:

  1. Looker 會尋找 external_user_id = pied_piper 的現有使用者帳戶。如果沒有,Looker 會建立具有該 external_user_id 的新使用者帳戶。

  2. 現有使用者的帳戶詳細資料 (包括權限、模型、群組 (如有指定) 和使用者屬性值 (如有指定)),會遭到網址中指定的帳戶詳細資料覆寫。

  3. Looker 會驗證使用者身分,並在瀏覽器中儲存工作階段 Cookie,為該使用者建立工作階段。

  4. 接著,Looker 會重新導向至 create_sso_embed_url 呼叫中指定的目標網址或重新導向網址:

    https://mylookerinstance.cloud.looker.com/embed/dashboards/17

    您可以在原始簽署的嵌入網址中,以編碼相對網址的形式查看這個重新導向網址:

    %2Fembed%2Fdashboards%2F17

雖然步驟 1 到 3 會在背景自動執行,且使用者只會看到最終結果 (資訊主頁本身),但這些步驟與一般非嵌入式 Looker 使用者驗證的步驟基本上相同。假設您希望使用者透過使用者名稱和密碼憑證登入,程序會如下所示:

  1. 您 (Looker 管理員) 前往「管理員 - 使用者」面板,並使用搜尋列檢查該使用者是否已有使用者帳戶。如果沒有,請建立新的使用者帳戶。

  2. 您 (Looker 管理員) 按一下「管理」-「使用者」面板中使用者旁邊的「編輯」,然後為使用者佈建權限、模型、群組、使用者屬性值和其他值。

  3. 使用者前往 https://mylookerinstance.cloud.looker.com/login 的登入頁面,然後輸入使用者名稱和密碼。Looker 會驗證使用者身分,並在瀏覽器中儲存工作階段 Cookie,為該使用者建立工作階段。

  4. 接著 Looker 會重新導向至到達網頁 (通常是 https://mylookerinstance.cloud.looker.com/browse)。

請注意,工作階段 Cookie 會套用至瀏覽器視窗中的每個分頁。如果使用者從 https://mylookerinstance.cloud.looker.com/browse 開始,開啟新的瀏覽器分頁,然後前往他們有權存取的任何頁面,系統會使用原始瀏覽器分頁中已建立的工作階段 Cookie,如常載入該頁面。

嵌入使用者也適用相同規定。嵌入使用者在使用者介面中可存取的頁面較為受限,只能存取含有 /embed 前置字元的 Look、資訊主頁和探索網址。但他們仍可手動前往使用者帳戶詳細資料允許存取的任何資訊主頁。假設原始簽署的嵌入網址會將您重新導向至某個瀏覽器分頁中的 https://mylookerinstance.cloud.looker.com/embed/dashboards/17。接著,您開啟新的瀏覽器分頁,並載入位於相同資料夾 (因此具有相同存取限制) 的其他嵌入式資訊主頁: https://mylookerinstance.cloud.looker.com/embed/dashboards/19.

雖然原始簽署的嵌入網址中指定的重新導向網址是資訊主頁 17,但您會發現,如果手動在瀏覽器分頁中輸入網址,資訊主頁 19 會如預期載入。請注意,載入其他資訊主頁時,不需要其他簽署的嵌入網址。

這裡的重點是,網址中建立的所有使用者帳戶詳細資料 (權限、使用者屬性等) 都會套用至整個使用者工作階段,而不只是原始經簽署的網址中指定的特定資訊主頁。換句話說,顧名思義,使用者屬性是使用者的功能,而非資訊主頁的功能,應適用於判斷整個應用程式中特定使用者的存取層級,而不僅限於特定分頁。

同時存取多個品牌

請注意,您可能也有外部合作夥伴,他們可能擁有或管理多個品牌。在本例中,合作夥伴同時管理 Pied Piper 和 Hooli 品牌。

從非嵌入式角度來看

簽署的嵌入使用者工作階段與一般非嵌入 Looker 使用者工作階段的運作方式基本上相同,因此不妨以一般非嵌入 Looker 使用者工作階段為背景,重新架構先前所述的問題方法,並分解這些步驟,協助瞭解如何以更穩健的方式實作這項解決方案。如果您要向可存取 Looker UI 的標準 BI 使用者提供操作說明,工作流程如下:

  1. 在「管理」-「使用者」頁面建立兩個不同的使用者帳戶。
    1. 在最初招攬到使用者帳戶的編輯頁面中,將品牌使用者屬性值設為 pied_piper
    2. 在第二個使用者帳戶的編輯頁面中,將品牌使用者屬性值設為 hooli
  2. 您將兩個使用者帳戶的帳戶設定電子郵件傳送給合作夥伴。
  3. 合作夥伴會為每個帳戶設定專屬的電子郵件和密碼憑證。
  4. 將資訊主頁連結提供給合作夥伴。(https://mylookerinstance.cloud.looker.com/dashboards/17),並告知對方如要在品牌之間切換資訊主頁,必須返回另一個分頁的登入頁面,輸入其他使用者帳戶的電子郵件地址和密碼憑證,然後在該分頁中重新載入資訊主頁。

合作夥伴按照操作說明進行,但在第二個瀏覽器分頁中輸入 Hooli 使用者帳戶的使用者名稱和密碼,然後返回已載入 Pied Piper 資訊主頁的第一個分頁時,合作夥伴按下「重新載入」按鈕。令合作夥伴驚訝的是,資訊主頁顯示的竟然是 Hooli 資料!

到目前為止,您可能會想:

等等…這樣很不方便。那麼,最佳做法是什麼?

當然!這些情境有助於說明一項原則,這項原則在非嵌入情境中微不足道,但在嵌入情境的抽象概念中可能會遭到遮蔽:單一使用者應與單一 Looker 使用者帳戶建立關聯,並使用一組使用者屬性值。已簽署的嵌入說明文件中,我們對 external_user_id 的說明也清楚指出這一點。

Looker 會使用 external_user_id 區分已登入的嵌入使用者,因此每位使用者都必須有專屬 ID。

您可以為使用者建立任何字串的 external_user_id,只要該字串是該使用者的專屬 ID 即可。每個 ID 都會與一組權限、使用者屬性和模型建立關聯。單一瀏覽器一次只能支援一個 external_user_id 或使用者工作階段。工作階段期間無法變更使用者的權限或使用者屬性。

同時存取多個品牌 - 請勿這麼做

與任何可自訂的解決方案一樣,您應避免採用某些做法。舉例來說,如果應用程式使用先前顯示的 create_sso_embed_url 呼叫中的相同輸入內容,為 external_user_ids 產生網址,並在應用程式中建立新分頁,載入合作夥伴需要存取的每個資訊主頁,開發人員通常會採用這類解決方案,但這會導致使用者工作流程不正確:

  1. 前往 Pied Piper 資訊主頁分頁。
  2. 前往 Hooli 資訊主頁分頁。
  3. 返回 Pied Piper 資訊主頁分頁。
  4. 按下 Pied Piper 資訊主頁上的「重新載入」按鈕。

…Pied Piper 資訊主頁會顯示 Hooli 資料!

您可能會嘗試類似的做法,但改為對兩個 create_sso_embed_url 呼叫使用相同的 external_user_id test_user。但行為完全相同,分頁重新載入 Pied Piper 資訊主頁後,顯示的資料會是 Hooli 的資料。

如何確保每個品牌的資訊主頁只顯示該品牌的資料?

運用最佳做法

如要套用「非嵌入式觀點的解決方法」一節所述方法,您需要單一使用者屬性值,授予合作夥伴在應用程式中存取所有資料的權限。您可以為 brand 屬性使用半形逗號分隔值 Pied Piper,Hooli

{
  "target_url": "https://mylookerinstance.cloud.looker.com/embed/dashboards/17",
  "session_length": 300,
  "force_logout_login": true,
  "external_user_id": "test_user",
  "first_name": "Test",
  "last_name": "User",
  "permissions": ["access_data","see_user_dashboards"],
  "models": ["thelook"],
  "user_attributes": {"brand":"Pied Piper,Hooli"}
}

如要使用這個語法,請務必將使用者屬性設為「字串篩選器 (進階)」

請注意,如果使用者的資料存取層級有所變更,您仍可變更該使用者的屬性組合。舉例來說,如果合作夥伴取得第三方品牌的擁有權,您可以將該第三方品牌新增至為其品牌使用者屬性指定的半形逗號分隔清單。這樣一來,使用者登出並重新登入後,系統就會套用變更。

篩選資訊主頁結果

我知道使用者屬性必須指定使用者可在應用程式中存取的所有資料。但如果我以這種方式指定使用者屬性,我的資訊主頁就會顯示所有品牌的資料!如何將特定資訊主頁的結果範圍縮小至特定品牌?

如要篩選特定資訊主頁,請使用一般的資訊主頁篩選器!(現在看來這或許很明顯,但我們發現有些人在嵌入環境中套用篩選器時,只會使用使用者屬性,可能是因為 user_attributes 是已簽署嵌入網址中的參數,而篩選器不是。)

請務必要求提供篩選器值,並使用單選控制項選項,例如下拉式選單:

請確認篩選器已套用至所有必要圖塊的正確欄位:

現在合作夥伴可以從這兩個值中選取一個 (只能選取這兩個值),因為下拉式選單中的可用選項會受到使用者屬性限制:

預先填入資訊主頁篩選器

好的,現在資訊主頁可以篩選特定品牌,但我想在使用者於應用程式中載入該品牌的資訊主頁時,預先將篩選器值設為特定品牌。

同樣地,請思考這項功能在非嵌入式情境中的運作方式。如何將資訊主頁連結傳送給他人,並預先套用特定篩選器值?您可能已經注意到,選取篩選器值時,該篩選器值會顯示在資訊主頁的網址中:

create_sso_embed_url 呼叫的 target_url 中加入網址的該部分:

{
  "target_url": "https://mylookerinstance.cloud.looker.com/embed/dashboards/17?Brand=Hooli",
  "session_length": 300,
  "force_logout_login": true,
  "external_user_id": "test_user",
  "first_name": "Test",
  "last_name": "User",
  "permissions": ["access_data","see_user_dashboards"],
  "models": ["thelook"],
  "user_attributes": {"brand":"Pied Piper,Hooli"}
}

如果您使用嵌入 SDK,可以透過 withFilters 指定要套用至嵌入內容的初始篩選器:

https://looker-open-source.github.io/embed-sdk/classes/EmbedBuilder.html#withFilters

如果您使用自訂指令碼,請務必在路徑編碼前,將篩選器加入網址。篩選器字串中可能已編碼部分值 (例如 ?Brand=Pied+Piper 中的空格編碼為 +),因此這些值會在最終網址中經過雙重編碼。如要進一步瞭解這些細微差異,請參閱「SO embedded dashboard - set dashboard filter as part of URL?」Looker 社群貼文。如果仍無法套用篩選器,也歡迎在該社群貼文中提出任何問題。

隱藏資訊主頁篩選器

我知道如何設定資訊主頁的初始篩選器,但我不希望合作夥伴自行變更資訊主頁篩選器,篩選條件值應「僅」根據合作夥伴在應用程式中前往的資訊主頁而定。如何隱藏資訊主頁篩選器?

您可以使用主題達成這個目的。主題是付費功能,因此如果 Looker 執行個體尚未啟用這項功能,請與 Looker 銷售團隊聯絡,要求啟用這項功能。

啟用這項功能後,請前往「管理員 - 主題」頁面的「資訊主頁控制項」部分,然後取消勾選「顯示篩選器列」選項:

然後,您可以將主題設為預設,或在特定資訊主頁的網址中套用主題。同樣地,這會進入 create_sso_embed_url 呼叫的 target_url

{
  "target_url": "https://mylookerinstance.cloud.looker.com/embed/dashboards/17?Brand=Hooli&theme=test_theme",
  "session_length": 300,
  "force_logout_login": true,
  "external_user_id": "test_user",
  "first_name": "Test",
  "last_name": "User",
  "permissions": ["access_data","see_user_dashboards"],
  "models": ["thelook"],
  "user_attributes": {"brand":"Pied Piper,Hooli"}
}

如要進一步瞭解如何隱藏嵌入式資訊主頁篩選器,包括一些 Embed SDK 程式碼片段,請參閱這部 YouTube 教學影片:Embed Looker with custom filters (使用自訂篩選器嵌入 Looker)。

最終結果應與原始問題的使用者體驗相同:

但現在,由於篩選器值會編碼到應用程式內嵌的相應目標網址中,因此即使在分頁之間來回切換,每個品牌的資訊主頁都會一律顯示已篩選出正確品牌的資訊主頁。

以其他使用者身分測試

現在使用者體驗與我原本的設想非常接近。但在我的使用案例中,合作夥伴擁有不同權限和其他使用者設定,而具有 external_user_id=pied_piperexternal_user_id=hooli 的個別使用者沒有這些權限和設定,因此 UI 中可用的選項不同,整體使用者體驗也略有差異。我希望使用者能看到 pied_piper hooli 使用者看到的內容,就像使用者實際以這些身分登入一樣。我該如何達成這個目標?

如要讓使用者以個別品牌使用者的身分進行測試,您可以在應用程式中建構類似的 sudo 函式,當使用者以 Pied Piper 使用者身分 sudo 時,載入 external_user_id=pied_piper 的嵌入網址;當使用者以 Hooli 使用者身分 sudo 時,載入 external_user_id=hooli 的嵌入網址。如果應用程式使用 API,您也可以使用 login_user API 端點,以品牌使用者的身分透過 API 進行 sudo。

不過,請再次考量非嵌入式環境:在「管理」-「使用者」頁面中,您無法在多個分頁中同時以多個非嵌入式使用者身分執行 sudo,因為 sudo 工作階段會套用至整個瀏覽器視窗,就像所有其他使用者工作階段一樣。因此,您應設計 sudo,一次只能以一位使用者身分執行 sudo。而且,如果您仔細想想,這種設計更符合完美模擬您要 sudo 的使用者體驗。舉例來說,pied_piper 使用者只能存取 Pied Piper 資訊主頁,無法在其他分頁中開啟其他資訊主頁。因此,以這個使用者身分執行 sudo 時,您也不應能在不同分頁中開啟不同資訊主頁。

結論

希望這份指南對您有幫助,並讓您充分瞭解如何繼續建構 Looker 簽署嵌入內容!我們持續努力,希望 Looker 成為最靈活且功能強大的嵌入式資料分析服務,歡迎提供寶貴意見!如有任何問題或想瞭解詳情,歡迎前往 Looker 社群與我們交流,並參加社群活動。