埋め込み Looker コンテンツの行レベルのセグメンテーションを実装する

著者: シニア データ アナリストの Christopher Seymour、デベロッパー リレーションズ エンジニアの Dean Hicks

行レベルのセグメンテーションを使用すると、1 つ以上のデータベース フィールドに保存されている値に基づいて、個々のユーザーがアクセスできるデータを制限できます。このガイドでは、埋め込みの Looker コンテンツに行レベルのセグメンテーションを実装する方法について説明します。このガイドは次のセクションで構成されています。

はじめに

Looker の埋め込み機能は、Looker プロダクトの最も強力で価値の高い機能の一つです。このガイドをお読みの方は、すでに Looker コンテンツをアプリケーションに組み込んでいるか、近い将来に組み込む可能性があります。

このガイドでは、Looker の埋め込み機能の設計と、パートナーが複数のブランドへのアクセスを管理できるアプリケーションにセグメンテーションを実装する方法について説明します。このトピックについては詳しく説明しますが、読みづらくなりますが、このガイドは単純な問題を簡単に修正できるものではなく、Looker の埋め込み全体をより適切に管理するための構成要素であることに留意してください。

ユースケースの概要

このガイドでは、お客様の会社が Looker コンテンツをプロダクトに埋め込み、異なるデータスライスを表示する必要があるユーザー セグメントにサービスを提供する一般的なユースケースについて説明します。

この署名付き埋め込みのユースケースでは、自身が Looker インスタンスの管理者であると想定します。次の 2 種類の外部埋め込みユーザーを使用します。顧客は特定のブランドに関連するデータにのみアクセスでき、パートナーは、複数のブランドのデータにアクセスできます。製品を使用しているすべてのユーザーに表示するダッシュボードにいくつかのタイルがありますが、ダッシュボードにそのユーザーに固有のデータのみが表示されるように、ダッシュボードを各ユーザーごとに自動的にフィルタリングする必要があります。このドキュメントの例では、2 つの架空の会社(HooliPied Piper)を使用します。

製品というテーブルがあるとします。このテーブルには、ブランド別の製品指標が表示されます。各ブランドは、署名付き埋め込みアプリ内の異なる埋め込みユーザー(external_user_id が異なる)に対応しています。各埋め込みユーザーは自分のブランドのデータのみを表示できるため、ブランド ユーザー属性のアクセス フィルタを使用する Explore を作成します。

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

この Explore に基づくダッシュボードに、2 つのタイルがあります。1 つはブランドの名前を示し、もう 1 つはブランドの製品数を表示します。

create_sso_embed_url エンドポイントを使用して、埋め込みユーザーごとにこのダッシュボードの埋め込み URL を生成します。この例では、Pied Piper と Hooli の 2 つのブランドを使用しています。Pied Piper の create_sso_embed_url 呼び出しで使用するリクエスト本文を、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 用に生成した URL では、ダッシュボードが次のように表示されます。

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 用に生成された URL では、ダッシュボードが次のように表示されます。

Voilà!ダッシュボードは、各埋め込みユーザーのブランド ユーザー属性の値に従ってフィルタされます。

さらに詳しく

驚きの機能ですね。では、1 人のユーザーに複数のブランドへのアクセス権を付与する場合はどうでしょうか?自分のデータが関連するユーザーにのみ表示されるようにするにはどうすればよいですか?

お客様はLooker の署名付き埋め込み機能は、デベロッパーがユーザー向けに強力な独自の仕様に基づくデータ エクスペリエンスを作成できるようにすると同時に、データモデルとコンテンツ アクセス ポリシーで定義されたデータ ガバナンスを維持できるように設計されています。

強力なデータ エクスペリエンスを実現するには、データ ガバナンスが確実に機能することが不可欠です。以下では、最適なエクスペリエンスを設計するために役立つコンセプトとベスト プラクティスについて説明します。まず、この仕組みの概要を説明します。

Looker の署名付き埋め込みの基本

埋め込みコンテキストにおける Looker のユーザー認証と管理は、基本的には非埋め込みコンテキストと同じ方法で、根本的に他のほとんどのウェブ アプリケーションと同様に機能するという点に注意することが重要です。

Looker の署名付き埋め込みのコンテキストでは、署名付き認証手順、ユーザー設定、ダッシュボード自体がすべて 1 つの長く複雑な URL に統合されるため、混乱する可能性があります。ただし、その URL はセッションの確立に使用され、URL を短縮しても引き続き適用されます。このコンセプトを念頭に置くことで、優れたデータ エクスペリエンスを構築できます。

署名付き埋め込み URL の構造

Pied Piper のリクエスト本文を使用して create_sso_embed_url 呼び出しによって生成された署名付き埋め込み認証 URL の例を次に示します。

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

同じ URL をデコードして個別の行に分割すると、次のようになります。

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

この URL にアクセスすると、次のような処理が行われます。

  1. Looker は、external_user_id = pied_piper の既存のユーザー アカウントを検索します。存在しない場合は、その external_user_id を使用して新しいユーザー アカウントが作成されます。

  2. 既存のユーザーのアカウントの詳細(権限、モデル、グループ(指定されている場合)、ユーザー属性値(指定されている場合))は、URL で指定されたアカウントの詳細で上書きされます。

  3. Looker はユーザーを認証し、ブラウザにセッション Cookie を保存してそのユーザーのセッションを確立します。

  4. その後、Looker は、create_sso_embed_url 呼び出しで指定されたターゲット URL(リダイレクト URL)にリダイレクトします。

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

    このリダイレクト URL は、元の署名付き埋め込み URL でエンコードされた相対 URL として確認できます。

    %2Fembed%2Fdashboards%2F17

手順 1 ~ 3 はバックグラウンドで自動的に行われ、エンドユーザーには最終結果(ダッシュボード自体)のみが表示されますが、これらの手順は、埋め込み以外の通常の Looker ユーザーが認証する手順と基本的に同じです。ユーザーにユーザー名とパスワードの認証情報でログインしてほしいとします。このプロセスは次のようになります。

  1. Looker 管理者は、[Admin - Users] パネルに移動し、検索バーを使用して、このユーザーのユーザー アカウントがすでに存在するかどうかを確認します。ない場合は、新しいユーザー アカウントを作成します。

  2. Looker 管理者は [Admin - Users] パネルでユーザーの横にある [編集] をクリックし、権限、モデル、グループ、ユーザー属性値などの値でユーザーをプロビジョニングします。

  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 を使用して、ページが想定どおりに読み込まれます。

埋め込みユーザーも同様です。埋め込みユーザーには、UI でアクセスできるページがさらに制限されます。アクセスできる URL は、/embed 接頭辞が付いた Look、ダッシュボード、Explore の URL のみです。ただし、ユーザー アカウントの詳細でアクセス権が付与されているダッシュボードには、引き続き手動で移動できます。元の署名付き埋め込み URL が、1 つのブラウザタブで https://mylookerinstance.cloud.looker.com/embed/dashboards/17 にリダイレクトされるとします。次に、新しいブラウザタブを開き、同じフォルダにある別の埋め込みダッシュボード(同じアクセス制限がある)https://mylookerinstance.cloud.looker.com/embed/dashboards/19 を読み込みます。

元の署名付き埋め込み URL で指定されたリダイレクト URL はダッシュボード 17 用ですが、ブラウザのタブに URL を手動で入力すると、ダッシュボード 19 が想定どおりに読み込まれます。別のダッシュボードを読み込むために、別の署名付き埋め込み URL は必要ありませんでした。

ここで重要なのは、URL で設定されたユーザー アカウントの詳細(権限、ユーザー属性など)が、元のサイン付き URL で指定された特定のダッシュボードだけでなく、ユーザー セッション全体に適用されるということです。つまり、名前が示すように、ユーザー属性はダッシュボードの機能ではなくユーザーの機能であり、特定のタブだけでなく、アプリケーション全体で特定のユーザーのアクセスレベルを決定するために使用する必要があります。

複数のブランドに同時にアクセスする

複数のブランドを所有または管理している外部パートナーがいる場合も考慮してください。この例では、パートナーが Pied Piper と Hooli の両方のブランドを管理しています。

埋め込み以外の観点からのアプローチ

署名付き埋め込みユーザー セッションは、通常の埋め込み以外の Looker ユーザー セッションと基本的に同じように機能するため、前述した問題のあるアプローチを通常の埋め込み以外の Looker ユーザー セッションのコンテキストで捉え直し、そのステップを分解することで、このソリューションをより堅牢に実装する方法を理解するのに役立ちます。Looker UI にアクセスできる標準の BI ユーザーに手順を説明する場合のワークフローは次のとおりです。

  1. [Admin - Users] ページで、2 つの異なるユーザー アカウントを作成します。
    1. 最初のユーザー アカウントの編集ページで、ブランド ユーザー属性値を pied_piper に設定します。
    2. 2 番目のユーザー アカウントの編集ページで、ブランド ユーザー属性値を hooli に設定します。
  2. 両方のユーザー アカウントのアカウント設定メールをパートナーに送信します。
  3. パートナーは、アカウントごとに個別のメールとパスワードの認証情報を設定します。
  4. パートナーにダッシュボードへのリンクを付与します。(https://mylookerinstance.cloud.looker.com/dashboards/17)。ブランド間でダッシュボードを切り替えるには、別のタブのログインページに戻り、他のユーザー アカウントのメールとパスワードの認証情報を入力してから、そのタブで再度ダッシュボードに表示されます。

パートナーは手順に沿って操作します。ただし、2 番目のブラウザタブで Hooli ユーザー アカウントのユーザー名とパスワードを入力した後で、Piped Piper ダッシュボードがすでに読み込まれている最初のタブに戻り、パートナーが[再読み込み] ボタンをクリックします。驚いたことに、ダッシュボードには Hooli のデータが表示されています

ここで、こう考えるかもしれません。

待ってください。これは非常に不便です。では、最適な方法を教えてください。

はい、できます。これらのシナリオが、埋め込み以外のコンテキストではすでに自明であるが、埋め込みコンテキストの抽象化によって難読化される可能性がある原則を説明しています。1 人のユーザーを、単一のユーザー属性値のセットを持つ単一の Looker ユーザー アカウントに関連付ける必要がありますこれは、署名付き埋め込みのドキュメントexternal_user_id の説明でも明記されています。

Looker では、署名付き埋め込みユーザーの区別に external_user_id が使用されるため、各ユーザーに一意の ID を割り当てる必要があります。

任意の文字列を持つユーザーの external_user_id は、そのユーザーに固有のものであれば作成できます。各IDは、権限、ユーザー属性、モデルのセットに関連付けられています。1 つのブラウザが一度にサポートできるのは、1 つの external_user_id またはユーザー セッションだけです。セッション内でユーザーの権限やユーザー属性を変更することはできません。

複数のブランドに同時にアクセスする - やってはいけないこと

カスタマイズ可能なソリューションと同様に、避けるべきアプローチもあります。たとえば、アプリが前述の create_sso_embed_url 呼び出しで同じ入力を使用して両方の external_user_ids の URL を生成し、アプリ内に新しいタブを作成して、パートナーがアクセスする必要がある各ダッシュボードを読み込む実装などです。デベロッパーが次のようなソリューションを実装し、ユーザーのワークフローが正しく機能しないという問題がよく発生しています。

  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 のデータが表示されます。

各ブランドのダッシュボードにそのブランドのデータのみを表示するにはどうすればよいですか?

ベスト プラクティスを活用する

埋め込み以外の視点からのアプローチ セクションで説明されているアプローチを適用するには、アプリケーション全体でパートナーがアクセスする必要があるすべてのデータへのアクセス権を付与する、単一のユーザー属性値が必要です。これを行うには、ブランド属性(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"}
}

この構文が機能するためには、ユーザー属性が [String Filter (advanced)] に設定されていることを確認する必要があります。

データアクセス レベルに変更が加えられた場合、ユーザーのユーザー属性のセットを変更できます。たとえば、パートナーが 3 番目のブランドの所有権を取得している場合は、ブランド ユーザー属性に指定したカンマ区切りリストにその 3 番目のブランドを追加できます。ログアウトしてから再度ログインすると、変更が適用されます。

ダッシュボードの結果をフィルタする

ユーザー属性には、ユーザーがアプリケーション全体でアクセスできるすべてのデータを指定する必要があるということですね。しかし、この方法でユーザー属性を指定すると、これらすべてのブランドのデータがダッシュボードに表示されます。特定のダッシュボードの結果を特定のブランドに絞り込むにはどうすればよいですか?

特定のダッシュボードをフィルタする正しい方法は、通常のダッシュボード フィルタを使用することです。(これは明白なように思えるかもしれませんが、埋め込みコンテキストでフィルタを適用する唯一の方法としてのユーザー属性に行き詰まる人々もいます。おそらく、user_attributes は署名付き埋め込み URL のパラメータであり、フィルタはそうではないためです)。

フィルタ値を必須とし、プルダウンなどの単一選択コントロール オプションのいずれかを使用します。

必要なすべてのタイルの正しいフィールドにフィルタが適用されていることを確認します。

プルダウンで使用できるオプションはユーザー属性によって制限されるため、パートナーはこれらの 2 つの値(この 2 つのみ)を選択できます。

ダッシュボード フィルタの事前入力

これで、ダッシュボードを特定のブランドでフィルタできるようになりました。ただし、ユーザーがアプリでそのブランドのダッシュボードを読み込んだときに、フィルタの値をすでに特定のブランドに設定したいとします。

ここでも、埋め込み以外のコンテキストでどのように機能するかを考えると参考になります。特定のフィルタ値がすでに適用されているダッシュボードへのリンクを他のユーザーに送信するにはどうすればよいですか?フィルタ値を選択すると、そのフィルタ値がダッシュボードの URL に表示されることに気づいたかもしれません。

URL のその部分を、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

独自のカスタム スクリプトを使用している場合は、パスがエンコードされる前に URL にフィルタを追加する必要があります。一部の値はすでにフィルタ文字列でエンコードされている可能性があります(たとえば、?Brand=Pied+Piper に + としてエンコードされるスペースがある場合)。それらの値は最終ページ URL では二重エンコードされます。詳しくは、SO 埋め込みダッシュボード - URL の一部としてダッシュボード フィルタを設定しますか?をご覧ください。こうしたニュアンスに関するディスカッションの Looker コミュニティ投稿。フィルタを適用できない場合は、そのコミュニティ投稿に質問を追加してください。

ダッシュボード フィルタの非表示

ダッシュボードに初期フィルタを設定する方法はわかりましたが、パートナーがダッシュボード フィルタを自分で変更しないようにしたいのですが、フィルタ値は、パートナーがどのダッシュボードにアクセスしたかによってのみ決定する必要があります。ダッシュボード フィルタを非表示にするにはどうすればよいですか?

これにはテーマを使用できます。テーマは有料機能であるため、Looker インスタンスでまだ有効になっていない場合は、Looker セールスチームに連絡して有効にする必要があります。

この機能を有効にしたら、[Admin - Themes] ページの [ダッシュボードのコントロール] セクションに移動し、[フィルタバーを表示] オプションの選択を解除します。

その後、テーマをデフォルトとして設定するか、特定のダッシュボードの URL にテーマを適用できます。これは、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 を埋め込む」をご覧ください。

最終的な結果は、元の質問のユーザー エクスペリエンスとまったく同じになります。

ただし、フィルタ値はアプリに埋め込まれた各ターゲット URL にエンコードされるため、タブを切り替えても、各ブランドのダッシュボードには常に正しいブランドにフィルタされたダッシュボードが表示されます。

他のユーザーとしてテストする

ユーザー エクスペリエンスは、当初私が思い描いていたものに非常に近づいています。ただし、このユースケースでは、パートナーには external_user_id=pied_piperexternal_user_id=hooli を持つ個々のユーザーにはない異なる権限やユーザー設定があるため、UI で使用できるオプションが異なり、全体的にユーザー エクスペリエンスが若干異なります。 pied_piper hooli のユーザーと同じように、あたかもそれらのユーザーとしてログインしたかのように、ユーザーがすべてを見ることができるようにしたいのです。どのようにすればよいですか?

ユーザーが個々のブランド ユーザーとしてテストできるようにする場合は、同様の sudo 関数をアプリに構築して、ユーザーが Pied Piper ユーザーとして sudo を実行しているときに external_user_id=pied_piper の埋め込み URL を読み込みこみ、Hooli ユーザーとして sudo を実行しているときに external_user_id=hooli の埋め込み URL を読み込むことができます。また、アプリで API を使用する場合は、login_user API エンドポイントを使用して、API を持つブランド ユーザーとして sudo を行うこともできます。

ただし、非埋め込みコンテキストについてもう一度考えてみましょう。[Admin - Users] ページで、複数のタブで複数の非埋め込みユーザーとして sudo を同時に行うことはできません。sudo セッションは、他のすべてのユーザー セッションと同様に、ブラウザ ウィンドウ全体に適用されます。そのため、一度に 1 人だけのユーザーとして sudo を実行する sudo を設計する必要があります。考えてみると、この設計は、sudo を実行しているユーザーのエクスペリエンスを完全に模倣しています。たとえば、pied_piper ユーザーは Pied Piper ダッシュボードにのみアクセスでき、追加タブで追加ダッシュボードを開くことはできません。そのため、このユーザーとして sudo を実行している場合は、別のタブで別のダッシュボードを開くことはできません。

まとめ

このガイドがお役に立てば幸いです。Looker の署名付き埋め込みコンテンツを作成する準備が整ったと感じていらっしゃることでしょう。Google は、Looker を最も柔軟で堅牢な組み込み型データ分析サービスの開発に取り組んでおります。皆様からのご意見をお待ちしています。ご質問がある場合や詳細については、Looker コミュニティで交流し、コミュニティ イベントにご参加ください。