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

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

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

簡介

Looker 的嵌入功能是 Looker 產品最強大且實用的功能之一。如果您正在閱讀本指南,表示您可能已將 Looker 內容嵌入應用程式,或打算在近期內這麼做。

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

用途簡介

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

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

您有一個名為「products」的表格,其中顯示不同品牌的部分產品指標。在已簽署的嵌入應用程式中,每個品牌都對應至不同的嵌入使用者 (具有不同的 external_user_id)。由於每位嵌入使用者只能查看自己的品牌資料,因此您可以使用「品牌」使用者屬性,在探索中加入存取權限篩選器:

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

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

您可以使用 create_sso_embed_url 端點,為每位嵌入使用者產生此資訊主頁的嵌入網址。本範例使用兩個品牌:Pied Piper 和 Hooli。以下是 create_sso_embed_url 呼叫 Pied Piper 時使用的要求主體,其中包含 external_user_id pied_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_id hooli 要求主體:

{
  "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 產生的網址會以以下方式顯示資訊主頁:

Voilà!資訊主頁會根據每位嵌入使用者對品牌使用者屬性的值進行篩選。

深入探索

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

好消息!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 資訊主頁的首個分頁,然後按下「Reload」按鈕。合作夥伴驚訝地發現資訊主頁顯示了 Hooli 資料!

你可能會想:

等等...這很不方便。那麼,最適合的做法是什麼?

當然可以!這些情境有助於說明在非嵌入式內容中已屬於常見原則的規則,但可能會因嵌入式內容的抽象化而遭到掩蓋:單一真實使用者應與單一 Looker 使用者帳戶建立關聯,並使用單一組使用者屬性值。已簽署嵌入說明文件中對 external_user_id 的說明也清楚說明瞭這一點。

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

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

同時使用多個品牌 - 不建議做的事情

如同其他可自訂的解決方案,您也應避免採用某些方法。舉例來說,在實作中,應用程式會使用先前顯示的 create_sso_embed_url 呼叫中相同的輸入內容,為兩個 external_user_ids 產生網址,並在應用程式中建立新分頁,以載入合作夥伴需要存取的每個資訊主頁。我們經常看到開發人員實作類似以下的解決方案,導致使用者無法順利完成工作流程:

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

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

您可以嘗試類似的方法,但請為兩個 create_sso_embed_url 呼叫使用相同的 external_user_id test_user。但行為完全相同:一旦重新載入含有 Pied Piper 資訊主頁的分頁,就會改為顯示 Hooli 的資料。

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

採用最佳做法

如要套用「從非嵌入角度的做法」一節所述的方法,您需要使用單一使用者屬性值,授予合作夥伴應用程式中所有資料的存取權。只要在品牌屬性 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 嵌入式資訊主頁 - 將資訊主頁篩選器設為網址的一部分?」請參閱 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"}
}

如要進一步瞭解如何隱藏嵌入式資訊主頁篩選器,包括一些嵌入式 SDK 程式碼片段,請參閱這部 YouTube 教學課程「使用自訂篩選器嵌入 Looker」。

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

不過,由於篩選器值已編碼至嵌入應用程式的各個目標網址,因此即使您在分頁之間來回切換,每個品牌的資訊主頁仍會顯示篩選正確品牌的資訊主頁。

以其他使用者身分進行測試

現在的使用者體驗確實非常接近我最初的構想。但在我的用途中,合作夥伴擁有 external_user_id=pied_piperexternal_user_id=hooli 中沒有的不同權限和其他使用者設定,因此在使用者介面中提供不同的選項,整體使用者體驗也略有不同。我想讓使用者看到的內容與 pied_piper hooli 使用者看到的內容完全相同,就好像使用者實際以這些使用者的身分登入一樣。該如何完成這項操作?

如果您希望使用者能夠以個別品牌使用者的身分進行測試,可以在應用程式中建立類似的 sudo 函式,當使用者以 Pied Piper 使用者的身分執行 sudo 時,系統會載入 external_user_id=pied_piper 的嵌入網址,當使用者以 Hooli 使用者的身分執行 sudo 時,系統會載入 external_user_id=hooli 的嵌入網址。如果您的應用程式使用 API,您也可以使用 login_user API 端點,以品牌使用者身分執行 sudo。

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

結論

希望這份指南對您有所幫助,也讓您做好準備,繼續建構 Looker 簽署嵌入內容! 我們會持續致力於讓 Looker 成為最靈活且可靠的嵌入式資料分析服務,也希望能聽取你的意見回饋!如有任何問題或想進一步瞭解,歡迎前往 Looker 社群與我們互動,並參加社群活動。