Implementar a segmentação no nível da linha para conteúdo incorporado do Looker

Escrito por Christopher Seymour, analista sênior de dados, e Dean Hicks, engenheiro de relações com desenvolvedores

Com a segmentação no nível da linha, é possível limitar os dados que um usuário individual pode acessar com base nos valores armazenados em um ou mais campos do banco de dados. Este guia descreve métodos para implementar a segmentação no nível da linha no conteúdo incorporado do Looker e contém as seguintes seções:

Introdução

A funcionalidade de incorporação do Looker é um dos recursos mais poderosos e valiosos do produto. Se você está lendo este guia, provavelmente já está incorporando conteúdo do Looker ao seu app ou pretende fazer isso em breve.

Este guia tem o objetivo de ajudar você a entender melhor o design do recurso de incorporação do Looker e como implementar a segmentação em um aplicativo em que os parceiros podem gerenciar o acesso a várias marcas. Como nos aprofundamos no assunto, a leitura é um pouco longa. Portanto, tenha em mente que este guia não é uma solução rápida para um problema simples, mas sim um elemento básico para ajudar você a gerenciar melhor todo o caso de uso de incorporação do Looker.

Visão geral do caso de uso

Neste guia, descrevemos um caso de uso comum em que sua empresa incorpora conteúdo do Looker ao produto e veicula segmentos de usuários que precisam ver diferentes partes dos dados.

Para este caso de uso de incorporação assinada, suponha que você seja o administrador da sua instância do Looker. Você trabalha com dois tipos de usuários de incorporação externa: clientes, que só podem acessar dados relacionados à marca deles, e parceiros, que podem acessar dados de várias marcas. Você tem um painel com alguns blocos que mostra para todos os clientes que usam seu produto, mas precisa que o painel seja filtrado automaticamente para cada cliente, de modo que os painéis mostrem apenas os dados específicos de cada cliente. Os exemplos neste documento usam duas empresas fictícias: Hooli e Pied Piper.

Você tem uma tabela chamada produtos, que mostra algumas métricas de produtos para diferentes marcas. Cada marca corresponde a um usuário de incorporação diferente (com um external_user_id diferente) no app de incorporação assinado. Como cada usuário incorporado deve poder ver apenas os dados da própria marca, há uma Análise que usa um filtro de acesso em um atributo de usuário brand:

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

Você tem um dashboard baseado nessa Análise e com dois blocos: um mostra o nome da marca e o outro, o número de produtos dela.

Você usa o endpoint create_sso_embed_url para gerar URLs de incorporação desse painel para cada usuário. Este exemplo usa duas marcas: Pied Piper e Hooli. Este é o corpo da solicitação usado na chamada create_sso_embed_url para o flautista, com 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"}
}

O URL que você gerou para o Pied Piper exibe o painel da seguinte forma:

Este é o corpo da solicitação usado na chamada create_sso_embed_url para Hooli, com 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"}
}

O URL gerado para a Hooli mostra o painel da seguinte maneira:

Voilà! O painel é filtrado de acordo com o valor de cada usuário incorporado para o atributo de usuário brand.

Indo mais a fundo

Muito legal! Mas e se eu quiser dar acesso a várias marcas a um único usuário? Como posso garantir que meus dados sejam acessados apenas por usuários relevantes?

Boas notícias! O recurso de incorporação assinado do Looker foi projetado para capacitar os desenvolvedores a criar experiências de dados avançadas e personalizadas para os usuários, garantindo que a governança de dados definida pelo seu modelo de dados e políticas de acesso ao conteúdo seja mantida.

Garantir que a governança de dados seja controlada é fundamental para oferecer essa experiência poderosa. Continue lendo para explorar alguns conceitos e práticas recomendadas que você pode usar para criar a experiência que funciona melhor para você. Primeiro temos uma breve visão geral de como tudo isso funciona.

Noções básicas da incorporação assinada do Looker

É importante lembrar que a autenticação e o gerenciamento de usuários do Looker no contexto de incorporação funcionam basicamente da mesma forma que no contexto sem incorporação e da mesma forma que a maioria dos outros aplicativos da Web.

Isso pode ser confuso no contexto de incorporação assinada do Looker, porque a etapa de autenticação assinada, as configurações do usuário e o próprio painel são combinados em um URL longo e complexo. No entanto, esse URL é usado para estabelecer a sessão, que ainda se aplica mesmo depois que o URL é encurtado. Ter esse conceito em mente ajudará muito no seu sucesso na criação de ótimas experiências de dados.

Estrutura de URL de incorporação assinado

Veja um dos URLs de autenticação de incorporação assinados gerados pela chamada create_sso_embed_url com o corpo da solicitação para o 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

Veja o mesmo URL decodificado e dividido em linhas individuais:

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

Quando você acessa esse URL, acontecem algumas coisas:

  1. O Looker procura uma conta de usuário com external_user_id = pied_piper. Se não houver nenhuma, o Looker criará uma nova conta de usuário com esse external_user_id.

  2. Os detalhes da conta do usuário existente, incluindo permissões, modelos, grupos (se especificados), valores de atributo do usuário (se especificados), são substituídos pelos detalhes da conta especificados no URL.

  3. O Looker autentica o usuário e estabelece uma sessão para ele armazenando um cookie de sessão no navegador.

  4. O Looker redireciona para o URL de destino ou de redirecionamento especificado na chamada create_sso_embed_url:

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

    É possível ver esse URL de redirecionamento como um URL relativo codificado no URL de incorporação original assinado:

    %2Fembed%2Fdashboards%2F17

Embora as etapas de 1 a 3 aconteçam automaticamente em segundo plano e o usuário final veja o resultado final (o próprio painel), elas são basicamente as mesmas que um usuário normal do Looker sem incorporação. Suponha que você queira que um usuário faça login com as credenciais de usuário e senha. O processo é parecido com este:

  1. Você (o administrador do Looker) acessa o painel "Administrador - Usuários" e usa a barra de pesquisa para verificar se já existe uma conta de usuário para esse usuário. Caso contrário, você cria uma nova conta de usuário.

  2. Você (o administrador do Looker) clica em Editar ao lado do usuário no painel "Administrador - Usuários" e provisiona o usuário com permissões, modelos, grupos, valores de atributo do usuário e outros valores.

  3. O usuário acessa a página de login em https://mylookerinstance.cloud.looker.com/login e digita o nome de usuário e a senha. O Looker autentica o usuário e estabelece uma sessão para ele armazenando um cookie de sessão no navegador.

  4. Em seguida, o Looker redireciona para a página de destino (geralmente https://mylookerinstance.cloud.looker.com/browse).

O cookie de sessão será aplicado a todas as guias na janela do navegador. Se o usuário começar em https://mylookerinstance.cloud.looker.com/browse, abrir uma nova guia do navegador e navegar para qualquer página a que as permissões concedem acesso, a página será carregada conforme esperado usando o cookie de sessão já estabelecido na guia original do navegador.

O mesmo vale para usuários incorporados. Os usuários incorporados são um pouco mais limitados em quais páginas eles podem acessar na UI. Eles só podem acessar URLs de Look, dashboard e Explore com o prefixo /embed. No entanto, eles ainda podem navegar manualmente para qualquer painel a que os detalhes da conta de usuário permitam acesso. Suponha que o URL de incorporação assinado original redirecione você para https://mylookerinstance.cloud.looker.com/embed/dashboards/17 em uma guia do navegador. Em seguida, você abre uma nova guia do navegador e carrega um dashboard de incorporação diferente que reside na mesma pasta (e, portanto, tem as mesmas restrições de acesso): https://mylookerinstance.cloud.looker.com/embed/dashboards/19:

Embora o URL de redirecionamento especificado no URL de incorporação assinado original tenha sido para o painel 17, o painel 19 é carregado como esperado se você inserir o URL manualmente em uma guia do navegador. Outro URL de incorporação assinado não foi necessário para carregar um painel diferente.

O principal insight aqui é que todos os detalhes da conta de usuário estabelecidos no URL (permissões, atributos do usuário etc.) são aplicados a toda a sessão do usuário, não apenas ao painel específico especificado no URL assinado original. Em outras palavras, como o nome indica, os atributos do usuário são um recurso do usuário, não um recurso do painel, e devem ser usados para determinar os níveis de acesso de um usuário específico em todo o aplicativo, não apenas em uma guia específica.

Como acessar várias marcas ao mesmo tempo

Considere que você também tem parceiros externos que podem ter ou gerenciar várias marcas. Neste exemplo, um parceiro gerencia as marcas Pied Piper e Hooli.

A abordagem de uma perspectiva não integrada

As sessões de usuários incorporadas assinadas funcionam basicamente da mesma forma que as sessões normais de usuários do Looker não incorporadas. Por isso, pode ser útil reformular a abordagem problemática descrita anteriormente no contexto de uma sessão de usuário normal e não incorporada do Looker e detalhar essas etapas para ajudar a entender como implementar essa solução de maneira mais robusta. Confira como seria esse fluxo de trabalho se você estivesse dando instruções a um usuário padrão de BI que tem acesso à interface do Looker:

  1. Você cria duas contas de usuário diferentes na página Administrador – Usuários.
    1. Na página de edição da primeira conta de usuário, defina o valor do atributo de usuário brand como pied_piper.
    2. Na página de edição da segunda conta de usuário, você define o valor do atributo do usuário marca como hooli.
  2. Você envia e-mails de configuração das duas contas de usuário ao parceiro.
  3. O parceiro configura credenciais de e-mail e senha separadas para cada conta.
  4. Você fornece ao parceiro o link para o painel. (https://mylookerinstance.cloud.looker.com/dashboards/17) e diga que, para alternar o painel entre as marcas, ele precisa voltar à página de login em outra guia, inserir as credenciais de e-mail e senha da outra conta de usuário e carregar o painel novamente nessa guia.

O parceiro segue as instruções. No entanto, depois de inserir o nome de usuário e a senha da conta de usuário do Hooli na segunda guia do navegador e voltar para a primeira guia em que o painel do flautista já estava carregado, o parceiro pressiona o botão Atualizar. Para a surpresa do parceiro, o painel mostra os dados da Hooli.

Então, agora você deve estar pensando:

Espera aí… isso é muito inconveniente. Qual é a melhor maneira de fazer isso?

Com certeza! Esses cenários ajudam a ilustrar um princípio que já é trivial no contexto não incorporado, mas que pode ser obscurecido pelas abstrações do contexto incorporado: um único usuário humano precisa ser associado a uma única conta de usuário do Looker com um único conjunto de valores de atributo do usuário. Isso também fica claro na explicação sobre o external_user_id na documentação de incorporação assinada.

O Looker usa external_user_id para diferenciar os usuários de incorporação assinados. Portanto, cada usuário precisa ter um ID exclusivo.

É possível criar um external_user_id para um usuário com qualquer string, desde que seja exclusivo para esse usuário. Cada ID é associado a um conjunto de permissões, atributos de usuário e modelos. Um único navegador pode oferecer suporte a apenas uma external_user_id ou sessão de usuário por vez. Não é possível fazer mudanças nas permissões ou nos atributos de um usuário durante a sessão.

Acessar várias marcas ao mesmo tempo: o que NÃO fazer

Como acontece com qualquer solução personalizável, existem certas abordagens que você deve evitar. Por exemplo, uma implementação em que o app gera os URLs para as duas external_user_ids usando as mesmas entradas na chamada create_sso_embed_url mostrada anteriormente e cria uma nova guia no app para carregar cada painel que o parceiro precisa acessar. É comum os desenvolvedores implementarem soluções como essa, o que resulta em um fluxo de trabalho incorreto para o usuário:

  1. Acesse a guia do painel Pied Piper.
  2. Acesse a guia do painel da Hooli.
  3. Volte para a guia do painel do flautista.
  4. Clique no botão Reload no painel do Pied Piper.

...o painel do flautista mostra os dados do Hooli!

Você pode tentar uma abordagem semelhante, mas use o mesmo test_user external_user_id para as duas chamadas de create_sso_embed_url. Mas o comportamento é exatamente o mesmo: quando a guia é recarregada com o painel do Pied Piper, ela mostra os dados do Hooli.

Como posso garantir que o painel de cada marca mostre apenas os dados dela?

Uso das práticas recomendadas

Para aplicar a abordagem descrita na seção A abordagem a partir de uma perspectiva não incorporada, você precisará de um único valor de atributo de usuário que conceda acesso a TODOS os dados aos quais o parceiro deve ter acesso em todo o aplicativo. Para fazer isso, use um valor separado por vírgulas para o atributo marca 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"}
}

Para que essa sintaxe funcione, verifique se o atributo do usuário está definido como Filtro de string (avançado):

Você ainda poderá alterar o conjunto de atributos de um usuário se algo for alterado nos níveis de acesso aos dados. Por exemplo, se o parceiro assumir a propriedade de uma terceira marca, você poderá adicionar essa terceira marca à lista separada por vírgulas que você especificou para o atributo de usuário brand. Dessa forma, quando eles saírem e entrarem novamente, as alterações serão aplicadas.

Como filtrar os resultados do painel

Entendi que os atributos de usuário precisam especificar todos os dados que um usuário pode acessar no aplicativo. Mas, se eu especificar os atributos do usuário dessa forma, os dados de todas essas marcas vão aparecer no meu painel. Como restringir os resultados de um painel específico a uma marca específica?

A maneira correta de filtrar um painel específico é usar os filtros normais de painel. Isso pode parecer óbvio agora, mas algumas pessoas ficam presas nos atributos do usuário como a única maneira de aplicar filtros no contexto de incorporação. Talvez o user_attributes seja um parâmetro no URL de incorporação assinado, e os filtros não sejam.

Certifique-se de exigir um valor de filtro e use uma das opções de controle de seleção única, como o menu suspenso:

Verifique se o filtro foi aplicado ao campo correto em todos os blocos necessários:

Agora, o parceiro pode escolher entre esses dois valores (e apenas esses dois), porque as opções disponíveis no menu suspenso são limitadas pelos atributos do usuário:

Preencher os filtros do painel

Agora o painel pode ser filtrado para uma marca específica, mas eu gostaria que o valor do filtro já estivesse definido para uma marca específica quando o usuário carregar o painel dessa marca no meu app.

Novamente, é útil pensar em como isso funciona no contexto não incorporado. Como enviar a alguém um link para um painel que já tenha um valor de filtro específico aplicado? Você pode ter notado que, quando você seleciona um valor de filtro, esse valor aparece no URL do painel:

Inclua essa parte do URL no target_url para a chamada create_sso_embed_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"}
}

Se você estiver usando o SDK de incorporação, poderá usar withFilters para especificar filtros iniciais a serem aplicados ao conteúdo incorporado:

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

Se você usa seu próprio script personalizado, adicione o filtro ao URL antes que o caminho seja codificado. Alguns valores já podem estar codificados na string de filtro (por exemplo, há um espaço codificado como + em ?Brand=Pied+Piper). Portanto, esses valores serão codificados duas vezes no URL final. Confira "SO integrado dashboard - set dashboard filter as part of URL?". Confira a postagem da Comunidade do Looker para saber mais sobre essas nuances. Se você ainda não conseguir aplicar os filtros, essa postagem na Comunidade também é um bom lugar para tirar dúvidas.

Como ocultar os filtros do painel

Ok, entendo como definir os filtros iniciais nos meus dashboards, mas também não quero que o parceiro altere os filtros do dashboard por conta própria. O valor do filtro deve ser determinado APENAS pelo painel que o parceiro acessou no meu aplicativo. Como faço para ocultar os filtros do dashboard?

Para isso, use temas. Os temas são um recurso pago. Se você ainda não ativou esse recurso na sua instância do Looker, entre em contato com a equipe de vendas do Looker.

Depois que esse recurso for ativado, acesse a seção Controles do painel em "Administrador – Temas", onde você pode limpar a opção Barra de filtros de exibição:

Em seguida, é possível definir o tema como padrão ou aplicar o tema no URL dos painéis específicos. Novamente, isso iria para o target_url da chamada create_sso_embed_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"}
}

Neste tutorial do YouTube Incorporar o Looker com filtros personalizados, há mais informações sobre como ocultar filtros do painel de incorporação, incluindo alguns snippets de código do SDK de incorporação.

O resultado final precisa ser idêntico à experiência do usuário da pergunta original:

No entanto, como os valores do filtro são codificados nos respectivos URLs de destino incorporados ao app, o painel de cada marca sempre vai mostrar o painel filtrado para a marca correta, mesmo quando você alternar entre as guias.

Testar como outros usuários

Agora, a experiência do usuário parece muito parecida com o que eu imaginava. Mas, no meu caso de uso, o parceiro tem permissões e outras configurações que os usuários individuais com external_user_id=pied_piper e external_user_id=hooli não têm, o que leva a opções diferentes disponíveis na UI e a uma experiência do usuário um pouco diferente no geral. Quero que os usuários vejam tudo exatamente como o pied_piper e o hooli veem, como se a pessoa tivesse feito login como esses usuários. Como posso fazer isso?

Se você quiser que um usuário possa testar como cada um dos usuários individuais da marca, crie uma função sudo semelhante no app que carregue os URLs de incorporação para external_user_id=pied_piper quando o usuário estiver usando o sudo como usuário do Pied Piper e os URLs de incorporação para external_user_id=hooli quando o usuário estiver usando o sudo como usuário do Hooli. Também é possível usar o endpoint da API login_user para sudo como o usuário da marca com a API se o app usar a API.

No entanto, se você pensar sobre o contexto não incorporado novamente: na página Administrador - Usuários, não é possível executar o sudo como vários usuários não incorporados ao mesmo tempo em várias guias. A sessão sudo é aplicada a toda a janela do navegador, assim como todas as outras sessões de usuário. Portanto, você deve projetar "sudo" como "sudo" como um usuário por vez. E, se você pensar sobre isso, esse design é mais consistente com a imitação perfeita da experiência dos usuários com quem você está executando o sudo. O usuário pied_piper, por exemplo, tem acesso somente ao painel do Pied_piper e não pode abrir painéis adicionais em guias adicionais. Portanto, não será possível abrir diferentes painéis em diferentes guias ao usar o sudo como esse usuário.

Conclusão

Esperamos que este guia tenha sido útil e que você esteja preparado para avançar na criação do seu conteúdo incorporado assinado pelo Looker. Trabalhamos continuamente para fazer do Looker a opção mais flexível e robusta de análise de dados incorporados. Por isso, queremos seu feedback. Se você tiver dúvidas ou quiser saber mais, entre em contato com a nossa equipe na Comunidade Looker e participe dos nossos eventos da comunidade.