Incorporação sem cookies

Quando o Looker é incorporado a um iframe usando a incorporação assinada, alguns navegadores usam uma política de cookies que bloqueia cookies de terceiros. Os cookies de terceiros são rejeitados quando o iframe incorporado é carregado de um domínio diferente daquele que carrega o aplicativo de incorporação. Em geral, é possível contornar essa limitação solicitando e usando um domínio personalizado. No entanto, os domínios personalizados não podem ser usados em alguns cenários. É para esses cenários que a incorporação sem cookies do Looker pode ser usada.

Como funciona a incorporação sem cookies?

Quando os cookies de terceiros não estão bloqueados, um cookie de sessão é criado quando um usuário faz login no Looker pela primeira vez. Esse cookie é enviado com cada solicitação do usuário, e o servidor do Looker o usa para estabelecer a identidade do usuário que iniciou a solicitação. Quando os cookies são bloqueados, eles não são enviados com uma solicitação. Por isso, o servidor do Looker não consegue identificar o usuário associado à solicitação.

Para resolver esse problema, a incorporação sem cookies do Looker associa tokens a cada solicitação que pode ser usada para recriar a sessão do usuário no servidor do Looker. É responsabilidade do aplicativo de incorporação receber esses tokens e disponibilizá-los para a instância do Looker que está sendo executada no iframe incorporado. O processo de obtenção e fornecimento desses tokens é descrito no restante deste documento.

Para usar qualquer uma das APIs, o aplicativo de incorporação precisa ser capaz de se autenticar na API Looker com privilégios de administrador. O domínio de incorporação também precisa estar listado na lista de permissões de domínios de incorporação ou, se você estiver usando o Looker 23.8 ou mais recente, o domínio de incorporação poderá ser incluído quando a sessão sem cookies for adquirida.

Como criar um iframe de incorporação do Looker

O diagrama de sequência a seguir ilustra a criação de um iframe de incorporação. Vários iframes podem ser gerados simultaneamente ou em sequência. Quando implementado corretamente, o iframe vai entrar automaticamente na sessão criada pelo primeiro iframe. O SDK de incorporação do Looker simplifica esse processo ao ingressar automaticamente na sessão atual. Para diretrizes sobre como evitar colisões de login simultâneas ao carregar vários iframes, consulte Práticas recomendadas para incorporar vários iframes sem cookies.

Um diagrama de sequência que ilustra a criação de um iframe de incorporação.

  1. O usuário realiza uma ação no aplicativo de incorporação que resulta na criação de um iframe do Looker.
  2. O cliente do aplicativo de incorporação adquire uma sessão do Looker. O SDK de incorporação do Looker pode ser usado para iniciar essa sessão, mas é necessário fornecer um URL de endpoint ou uma função de callback. Se uma função de callback for usada, ela vai chamar o servidor do aplicativo de incorporação para adquirir a sessão de incorporação do Looker. Caso contrário, o SDK de incorporação vai chamar o URL do endpoint fornecido.
  3. O servidor do aplicativo de incorporação usa a API Looker para adquirir uma sessão de incorporação. Essa chamada de API é semelhante ao processo de assinatura de incorporação assinada do Looker, porque aceita a definição do usuário de incorporação como entrada. Se já houver uma sessão de incorporação do Looker para o usuário que está fazendo a chamada, o token de referência da sessão associado precisa ser incluído na chamada. Isso será explicado em mais detalhes na seção Adquirir sessão deste documento.
  4. O processamento do endpoint da sessão de incorporação de aquisição é semelhante ao endpoint /login/embed/(signed url) assinado, porque espera a definição do usuário de incorporação do Looker como o corpo da solicitação, em vez de no URL. O processo do endpoint de aquisição de sessão de incorporação valida e, em seguida, cria ou atualiza o usuário de incorporação. Ele também pode aceitar um token de referência de sessão atual. Isso é importante porque permite que vários iframes incorporados do Looker compartilhem a mesma sessão. O usuário incorporado não será atualizado se um token de referência de sessão for fornecido e a sessão não tiver expirado. Isso é útil quando um iframe é criado usando um URL de incorporação assinado e outros são criados sem um URL de incorporação assinado. Nesse caso, os iframes sem URLs de incorporação assinados vão herdar o cookie da primeira sessão.
  5. A chamada de API Looker retorna quatro tokens, cada um com um time to live (TTL):
    • Token de autorização (TTL = 30 segundos)
    • Token de navegação (TTL = 10 minutos)
    • Token de API (TTL = 10 minutos)
    • Token de referência da sessão (TTL = ciclo de vida restante da sessão)
  6. O servidor do aplicativo de incorporação precisa acompanhar os dados retornados pelo Looker e associá-los ao usuário que faz a chamada e ao user agent do navegador desse usuário. As sugestões de como fazer isso estão na seção Gerar tokens deste documento. Essa chamada vai retornar o token de autorização, um token de navegação e um token de API, além de todos os TTLs associados. O token de referência da sessão precisa ser protegido e não pode ser exposto no navegador de chamada.
  7. Depois que os tokens forem retornados ao navegador, um URL de login de incorporação do Looker precisará ser criado. O SDK de incorporação do Looker vai criar o URL de login de incorporação automaticamente. Para usar a API windows.postMessage para criar o URL de login incorporado, consulte a seção Como usar a API windows.postMessage do Looker deste documento para ver exemplos.

    O URL de login não contém os detalhes do usuário de incorporação assinada. Ele contém o URI de destino, incluindo o token de navegação, e o token de autorização como um parâmetro de consulta. O token de autorização precisa ser usado em até 30 segundos e só pode ser usado uma vez. Se forem necessários mais iframes, uma sessão de incorporação precisará ser adquirida novamente. No entanto, se o token de referência da sessão for fornecido, o token de autorização será associado à mesma sessão.

  8. O endpoint de login de incorporação do Looker determina se o login é para incorporação sem cookies, o que é indicado pela presença do token de autorização. Se o token de autorização for válido, ele vai verificar o seguinte:

    • A sessão associada ainda é válida.
    • O usuário incorporado associado ainda é válido.
    • O user agent do navegador associado à solicitação corresponde ao agente do navegador associado à sessão.
  9. Se as verificações da etapa anterior forem aprovadas, a solicitação será redirecionada usando o URI de destino contido no URL. Esse é o mesmo processo do login de incorporação assinada do Looker.

  10. Essa solicitação é o redirecionamento para iniciar o painel do Looker. Essa solicitação terá o token de navegação como parâmetro.

  11. Antes de o endpoint ser executado, o servidor do Looker procura o token de navegação na solicitação. Se o servidor encontrar o token, ele vai verificar o seguinte:

    • A sessão associada ainda é válida.
    • O user agent do navegador associado à solicitação corresponde ao agente do navegador associado à sessão.

    Se for válido, a sessão será restaurada para a solicitação, e a solicitação do painel será executada.

  12. O HTML para carregar o painel é retornado ao iframe.

  13. A interface do Looker em execução no iframe determina que o HTML do dashboard é uma resposta de incorporação sem cookies. Nesse momento, a interface do Looker envia uma mensagem ao aplicativo de incorporação para solicitar os tokens recuperados na etapa 6. A interface aguarda até receber os tokens. Se os tokens não chegarem, uma mensagem será exibida.

  14. O aplicativo de incorporação envia os tokens para o iframe incorporado do Looker.

  15. Quando os tokens são recebidos, a interface do Looker em execução no iframe inicia o processo para renderizar o objeto de solicitação. Durante esse processo, a UI vai fazer chamadas de API para o servidor do Looker. O token de API recebido na etapa 15 é injetado automaticamente como um cabeçalho em todas as solicitações de API.

  16. Antes de qualquer endpoint ser executado, o servidor do Looker procura o token da API na solicitação. Se o servidor encontrar o token, ele vai verificar o seguinte:

    • A sessão associada ainda é válida.
    • O user agent do navegador associado à solicitação corresponde ao agente do navegador associado à sessão.

    Se a sessão for válida, ela será restaurada para a solicitação, e a solicitação de API será executada.

  17. Os dados do painel são retornados.

  18. O painel é renderizado.

  19. O usuário tem controle sobre o painel.

Como gerar novos tokens

O diagrama de sequência a seguir ilustra a geração de novos tokens.

Um diagrama de sequência que ilustra a geração de novos tokens.

  1. A interface do Looker que está em execução no iframe incorporado monitora o TTL dos tokens de incorporação.
  2. Quando os tokens estão prestes a expirar, a interface do Looker envia uma mensagem de token de atualização para o cliente do aplicativo de incorporação.
  3. O cliente do aplicativo de incorporação solicita novos tokens de um endpoint implementado no servidor do aplicativo de incorporação. O SDK de incorporação do Looker vai solicitar novos tokens automaticamente, mas o URL do endpoint ou uma função de callback precisa ser fornecido. Se a função de callback for usada, ela vai chamar o servidor do aplicativo de incorporação para gerar novos tokens. Caso contrário, o SDK de incorporação vai chamar o URL do endpoint fornecido.
  4. O aplicativo de incorporação encontra o session_reference_token associado à sessão de incorporação. O exemplo fornecido no repositório Git do SDK de incorporação do Looker usa cookies de sessão, mas um cache distribuído do lado do servidor, como o Redis, também pode ser usado.
  5. O servidor do aplicativo de incorporação chama o servidor do Looker com uma solicitação para gerar tokens. Essa solicitação também exige tokens de API e de navegação recentes, além do user agent do navegador que iniciou a solicitação.
  6. O servidor do Looker valida o user agent, o token de referência da sessão, o token de navegação e o token da API. Se a solicitação for válida, novos tokens serão gerados.
  7. Os tokens são retornados ao servidor de aplicativos de incorporação que fez a chamada.
  8. O servidor do aplicativo de incorporação remove o token de referência da sessão da resposta e retorna o restante da resposta ao cliente do aplicativo de incorporação.
  9. O cliente do aplicativo de incorporação envia os tokens recém-gerados para a interface do Looker. O SDK de incorporação do Looker faz isso automaticamente. Os clientes de aplicativos incorporados que usam a API windows.postMessage serão responsáveis por enviar os tokens. Depois que a interface do Looker receber os tokens, eles serão usados nas próximas chamadas de API e navegações nas páginas.

Como implementar a incorporação sem cookies do Looker

A incorporação sem cookies do Looker pode ser implementada usando o SDK de incorporação do Looker ou a API windows.postMessage. Você pode usar o método do SDK de incorporação do Looker, mas também há um exemplo que mostra como usar a API windows.postMessage. Confira explicações detalhadas das duas implementações no arquivo README do SDK de incorporação do Looker. O repositório git do SDK de incorporação também contém implementações funcionais.

Como configurar a instância do Looker

A incorporação sem cookies compartilha características com a incorporação assinada do Looker.

Pré-requisitos

Para usar a incorporação sem cookies e expor os endpoints de API de incorporação sem cookies, um administrador do Looker precisa verificar e ativar os seguintes requisitos no painel Administrador do Looker:

  • Autenticação de SSO incorporado: no painel Administrador > Plataforma > Incorporar, ative a Autenticação de SSO incorporado. A incorporação sem cookies depende da função de autenticação de SSO incorporado como uma configuração básica.
  • Sessões persistentes: no painel Administrador > Autenticação > Sessões, ative as Sessões persistentes.
  • Permissões do usuário da API: verifique se as credenciais da API usadas para adquirir o token pertencem a um usuário do Looker com o papel de administrador ou um papel personalizado que contenha a permissão manage_embed_settings.

Como configurar o secret do JSON Web Token

Ao contrário da incorporação assinada do Looker, a incorporação sem cookies não usa a configuração Embed Secret. A incorporação sem cookies usa um JSON Web Token (JWT) na forma de uma configuração de Secret de JWT de incorporação, que pode ser definida ou redefinida na página Incorporação na seção Plataforma do menu Administrador.

Não é necessário definir o secret do JWT, porque a primeira tentativa de criar uma sessão de incorporação sem cookies vai criar o JWT. Evite redefinir esse token, porque isso vai invalidar todas as sessões de incorporação sem cookies ativas.

Ao contrário do secret de incorporação, o secret do JWT de incorporação nunca é exposto, porque é usado apenas internamente no servidor do Looker.

Implementação do cliente do aplicativo

Esta seção inclui exemplos de como implementar a incorporação sem cookies no cliente do aplicativo e contém as seguintes subseções:

Como instalar ou atualizar o SDK de incorporação do Looker

As seguintes versões do SDK do Looker são necessárias para usar a incorporação sem cookies:

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

Como usar o SDK de incorporação do Looker

Um novo método de inicialização foi adicionado ao SDK de incorporação para iniciar a sessão sem cookies. Esse método aceita duas strings de URL ou duas funções de callback. As strings de URL precisam fazer referência a endpoints no servidor do aplicativo de incorporação. Os detalhes de implementação desses endpoints no servidor de aplicativos são abordados na seção Implementação do servidor de aplicativos deste documento.

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

O exemplo a seguir mostra como os callbacks são usados. Os callbacks só devem ser usados quando é necessário que o aplicativo cliente de incorporação saiba o status da sessão de incorporação do Looker. Também é possível usar o evento session:status, o que torna desnecessário o uso de callbacks com o SDK de incorporação.

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
)

Como usar a API windows.postMessage do Looker

Confira um exemplo detalhado de como usar a API windows.postMessage nos arquivos message_example.ts e message_utils.ts no repositório Git do SDK de incorporação. Os destaques do exemplo estão detalhados aqui.

O exemplo a seguir demonstra como criar o URL para o iframe. A função de callback é idêntica ao exemplo de acquireEmbedSessionCallback mostrado anteriormente.

  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}`
  }

O exemplo a seguir demonstra como detectar solicitações de token, gerar novos tokens e enviá-los ao Looker. A função de callback é idêntica ao exemplo anterior de 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
  }

Implementação do servidor de aplicativos

Esta seção inclui exemplos de como implementar a incorporação sem cookies no servidor de aplicativos e contém as seguintes subseções:

Implementação básica

O aplicativo de incorporação precisa implementar dois endpoints do lado do servidor que vão invocar endpoints do Looker. Isso garante que o token de referência da sessão permaneça seguro. Estes são os endpoints:

  1. Adquirir sessão: se um token de referência de sessão já existir e ainda estiver ativo, as solicitações de uma sessão vão se juntar à sessão atual. A sessão de aquisição é chamada quando um iframe é criado.
  2. Gerar tokens: o Looker aciona chamadas para esse endpoint periodicamente.

Adquirir sessão

Este exemplo em TypeScript usa a sessão para salvar ou restaurar o token de referência da sessão. O endpoint não precisa ser implementado em 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
  }
}

A partir do Looker 23.8, o domínio de incorporação pode ser incluído quando a sessão sem cookies é adquirida. Essa é uma alternativa para adicionar o domínio de incorporação usando o painel Administrador > Incorporar do Looker. O Looker salva o domínio de incorporação no banco de dados interno do Looker, então ele não será mostrado no painel Administrador > Incorporar. Em vez disso, o domínio de incorporação é associado à sessão sem cookies e existe apenas durante a sessão. Leia as práticas recomendadas de segurança se decidir usar esse recurso.

Gerar tokens

Este exemplo em TypeScript usa a sessão para salvar ou restaurar o token de referência da sessão. O endpoint não precisa ser implementado em TypeScript.

É importante saber como lidar com as respostas 400, que ocorrem quando os tokens são inválidos. Embora uma resposta 400 não deva acontecer, se isso ocorrer, a prática recomendada é encerrar a sessão de incorporação do Looker. É possível encerrar a sessão de incorporação do Looker destruindo o iframe de incorporação ou definindo o valor de session_reference_token_ttl como zero na mensagem session:tokens. Se você definir o valor de session_reference_token_ttl como zero, o iframe do Looker vai mostrar uma caixa de diálogo de sessão expirada.

Uma resposta 400 não é retornada quando a sessão de incorporação expira. Se a sessão de incorporação tiver expirado, uma resposta 200 será retornada com o valor session_reference_token_ttl definido como zero.

  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
  }

Considerações de implementação

O aplicativo de incorporação precisa rastrear o token de referência da sessão e mantê-lo seguro. Esse token precisa ser associado ao usuário do aplicativo incorporado. O token de aplicativo de incorporação pode ser armazenado de uma das seguintes maneiras:

  • Na sessão do usuário do aplicativo incorporado
  • Em um cache do lado do servidor que está disponível em um ambiente em cluster
  • Em uma tabela de banco de dados associada ao usuário

Se a sessão for armazenada como um cookie, ele precisará ser criptografado. O exemplo no repositório do SDK de incorporação usa um cookie de sessão para armazenar o token de referência da sessão.

Quando a sessão de incorporação do Looker expirar, uma caixa de diálogo vai aparecer no iframe incorporado. Nesse ponto, o usuário não poderá fazer nada na instância incorporada. Quando isso ocorre, os eventos session:status são gerados, permitindo que o aplicativo de incorporação detecte o estado atual do aplicativo incorporado do Looker e realize algum tipo de ação.

Um aplicativo de incorporação pode detectar se a sessão de incorporação expirou verificando se o valor session_reference_token_ttl retornado pelo endpoint generate_tokens é zero. Se o valor for zero, a sessão de incorporação expirou. Considere usar uma função de callback para gerar tokens quando a incorporação sem cookies estiver sendo inicializada. A função de callback pode determinar se a sessão incorporada expirou e destruir o iframe incorporado como uma alternativa ao uso da caixa de diálogo padrão de sessão incorporada expirada.

Práticas recomendadas para incorporar vários iframes sem cookies

Ao incorporar vários iframes do Looker em uma única página sem cookies, cada iframe precisa de um authentication_token de uso único de acquire_embed_cookieless_session, mas todos os iframes na página precisam compartilhar um único session_reference_token. Siga estas práticas recomendadas para incorporar vários iframes sem cookies:

  • Adquirir a sessão uma vez e reutilizar session_reference_token: primeiro, adquira a sessão sem cookies uma vez, armazene em cache o session_reference_token retornado no servidor de back-end e transmita esse session_reference_token para as chamadas acquire_embed_cookieless_session subsequentes para outros iframes. Em seguida, o Looker anexa cada novo iframe à sessão atual e não atualiza o usuário incorporado.

  • Evite a aquisição paralela de sessões iniciais: se vários iframes forem montados ao mesmo tempo e seu back-end chamar acquire_embed_cookieless_session em paralelo sem transmitir um session_reference_token, o Looker vai tratar cada solicitação como um novo login, atualizar o usuário incorporado simultaneamente e criar sessões separadas. Solicitações de login simultâneas para o mesmo usuário incorporado podem causar contenção de bloqueio no servidor do Looker. Além disso, substituir o session_reference_token armazenado pela última resposta interrompe a atualização do token (generate_tokens_for_cookieless_session) nos iframes anteriores com um erro 400 Invalid input tokens provided.

  • Pré-carregar um iframe e usar a navegação no frame: para estabelecer a sessão do usuário incorporado antes de carregar o conteúdo, pré-carregue um iframe usando /embed/preload (ou o método .preload() no SDK de incorporação v2). Ao usar o SDK de Incorporação v2, também é possível navegar em um iframe atual usando métodos como connection.loadDashboard(DASHBOARD_ID) ou connection.loadUrl(EMBED_URL) em vez de criar outros iframes. Para mais informações, consulte Introdução ao SDK de incorporação.

Como executar o exemplo de incorporação sem cookies do Looker

O repositório do SDK de incorporação contém um servidor Node Express e um cliente escrito em TypeScript que implementa um aplicativo de incorporação. Os exemplos mostrados anteriormente foram retirados dessa implementação. As informações a seguir pressupõem que sua instância do Looker foi configurada para usar a incorporação sem cookies, conforme descrito anteriormente.

É possível executar o servidor assim:

  1. Clone o repositório do SDK de incorporação — git clone git@github.com:looker-open-source/embed-sdk.git
  2. Altere o diretório — cd embed-sdk
  3. Instale as dependências: npm install
  4. Configure o servidor, conforme mostrado na seção Configurar o servidor deste documento.
  5. Execute o servidor — npm run server

Configurar o servidor

Crie um arquivo .env na raiz do repositório clonado (incluído em .gitignore).

O formato é o seguinte:

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

Ao usar a incorporação sem cookies do Looker, os usuários que tentarem abrir links em uma nova guia ou janela do navegador (como detalhamentos de painéis, Análises ou downloads de documentos) poderão receber um erro HTTP 401 Unauthorized ou ser redirecionados para a página de login do Looker. Esse problema geralmente ocorre quando os cookies de terceiros estão desativados no navegador.

Causa

Para evitar vulnerabilidades de sequestro de sessão, um patch de segurança foi introduzido no Looker (versões 25.18.61+, 25.20.44+ e 26.0.22+) que intencionalmente parou de retornar cookies de sessão na resposta inicial de incorporação sem cookies. Como o navegador não recebe mais esse cookie de sessão, abrir um URL do Looker em uma nova guia ou janela perde o contexto de autenticação, fazendo com que a solicitação falhe.

Resolução e soluções alternativas

  • Faça upgrade do Looker: faça upgrade da instância do Looker para a versão 26.0.36 ou mais recente. Esta versão apresenta uma correção que adiciona com segurança um token único aos URLs abertos em uma nova janela durante uma sessão de incorporação sem cookies, restaurando a capacidade do usuário de abrir links seguros em novas guias.
  • Abrir links no mesmo iframe: se não for possível fazer o upgrade imediatamente, configure todos os links nos painéis incorporados para abrir no mesmo iframe, definindo os destinos dos links como _self (por exemplo, target="_self").
  • Rotear pelo aplicativo host: se for estritamente necessário abrir em uma nova guia ou janela, direcione o link para uma nova página no aplicativo host que inicialize um novo iframe de incorporação sem cookies, em vez de vincular diretamente à instância do Looker.
  • Usar a incorporação assinada com um domínio personalizado: como alternativa, use a incorporação assinada padrão com um domínio personalizado.