Intégration sans cookie

Lorsque Looker est intégré dans un iFrame à l'aide de l'intégration signée, certains navigateurs utilisent par défaut une règle concernant les cookies qui bloque les cookies tiers. Les cookies tiers sont refusés lorsque l'iFrame intégrée est chargée à partir d'un domaine différent de celui qui charge l'application d'intégration. Pour contourner cette limitation, vous pouvez généralement demander et utiliser un domaine personnalisé. Toutefois, dans certains cas, les domaines personnalisés ne peuvent pas être utilisés. C'est pour ces scénarios que l'intégration sans cookie Looker peut être utilisée.

Comment fonctionne l'intégration sans cookie ?

Lorsque les cookies tiers ne sont pas bloqués, un cookie de session est créé lorsqu'un utilisateur se connecte pour la première fois à Looker. Ce cookie est envoyé avec chaque requête utilisateur. Le serveur Looker l'utilise pour établir l'identité de l'utilisateur à l'origine de la requête. Lorsque les cookies sont bloqués, ils ne sont pas envoyés avec une requête. Le serveur Looker ne peut donc pas identifier l'utilisateur associé à la requête.

Pour résoudre ce problème, l'intégration sans cookie Looker associe des jetons à chaque requête pouvant être utilisés pour recréer la session utilisateur sur le serveur Looker. Il appartient à l'application d'intégration d'obtenir ces jetons et de les mettre à la disposition de l'instance Looker exécutée dans l'iFrame intégrée. Le processus d'obtention et de fourniture de ces jetons est décrit dans la suite de ce document.

Pour utiliser l'une ou l'autre API, l'application d'intégration doit pouvoir s'authentifier dans l'API Looker avec des droits d'administrateur. Le domaine d'intégration doit également figurer dans la liste d'autorisation des domaines d'intégration ou, si vous utilisez Looker 23.8 ou version ultérieure, il peut être inclus lorsque la session sans cookie est acquise.

Créer un iFrame d'intégration Looker

Le diagramme de séquence suivant illustre la création d'un iframe intégré. Plusieurs iFrames peuvent être générés simultanément ou à un moment donné. Lorsqu'il est implémenté correctement, l'iFrame rejoint automatiquement la session créée par la première iFrame. Le SDK d'ingestion Looker simplifie ce processus en rejoignant automatiquement la session existante.

Schéma de séquence illustrant la création d'un iframe intégré.

  1. L'utilisateur effectue une action dans l'application d'intégration qui entraîne la création d'un iframe Looker.
  2. Le client de l'application d'intégration acquiert une session Looker. Vous pouvez utiliser le SDK d'ingestion Looker pour lancer cette session, mais vous devez fournir une URL de point de terminaison ou une fonction de rappel. Si une fonction de rappel est utilisée, elle appelle le serveur d'application d'intégration pour acquérir la session d'intégration Looker. Sinon, le SDK d'intégration appelle l'URL du point de terminaison fournie.
  3. Le serveur d'application d'intégration utilise l'API Looker pour acquérir une session d'intégration. Cet appel d'API est semblable au processus de signature de l'intégration signée Looker, car il accepte la définition de l'utilisateur de l'intégration en entrée. Si une session d'intégration Looker existe déjà pour l'utilisateur appelant, le jeton de référence de session associé doit être inclus dans l'appel. Nous y reviendrons plus en détail dans la section Acquérir une session de ce document.
  4. Le traitement du point de terminaison de session d'intégration d'acquisition est semblable au point de terminaison /login/embed/{signed url) signé, en ce sens qu'il s'attend à ce que la définition de l'utilisateur d'intégration Looker figure dans le corps de la requête, et non dans l'URL. Le processus de point de terminaison de la session d'intégration permet de valider et de créer ou de mettre à jour l'utilisateur d'intégration. Il peut également accepter un jeton de référence de session existant. Cette approche est importante, car elle permet à plusieurs iframe intégrés Looker de partager la même session. L'utilisateur intégré ne sera pas mis à jour si un jeton de référence de session est fourni et que la session n'a pas expiré. Cela permet de prendre en charge le cas d'utilisation où une iFrame est créée à l'aide d'une URL d'intégration signée et que d'autres iFrames sont créées sans URL d'intégration signée. Dans ce cas, les iFrames sans URL d'intégration signées hériteront du cookie de la première session.
  5. L'appel d'API Looker renvoie quatre jetons, chacun avec une valeur TTL (Time To Live) :
    • Jeton d'autorisation (TTL = 30 secondes)
    • Jeton de navigation (TTL = 10 minutes)
    • Jeton d'API (TTL = 10 minutes)
    • Jeton de référence de session (TTL = durée de vie restante de la session)
  6. Le serveur d'application d'intégration doit suivre les données renvoyées par les données Looker et les associer à la fois à l'utilisateur appelant et à l'agent utilisateur du navigateur de l'utilisateur appelant. Pour ce faire, consultez la section Générer des jetons de ce document. Cet appel renvoie le jeton d'autorisation, un jeton de navigation et un jeton d'API, ainsi que tous les TTL associés. Le jeton de référence de session doit être sécurisé et ne pas être exposé dans le navigateur appelant.
  7. Une fois les jetons renvoyés au navigateur, une URL de connexion Looker intégrée doit être créée. Le SDK d'ingestion Looker crée automatiquement l'URL de connexion d'ingestion. Pour utiliser l'API windows.postMessage afin de créer l'URL de connexion intégrée, consultez la section Utiliser l'API windows.postMessage Looker de ce document pour obtenir des exemples.

    L'URL de connexion ne contient pas les informations sur l'utilisateur intégré connecté. Il contient l'URI cible, y compris le jeton de navigation, et le jeton d'autorisation en tant que paramètre de requête. Le jeton d'autorisation doit être utilisé dans les 30 secondes et ne peut être utilisé qu'une seule fois. Si des iFrames supplémentaires sont nécessaires, une session d'intégration doit être acquise à nouveau. Toutefois, si le jeton de référence de session est fourni, le jeton d'autorisation sera associé à la même session.

  8. Le point de terminaison de connexion d'intégration Looker détermine si la connexion est destinée à l'intégration sans cookie, ce qui est indiqué par la présence du jeton d'autorisation. Si le jeton d'autorisation est valide, il vérifie les éléments suivants:

    • La session associée est toujours valide.
    • L'utilisateur d'intégration associé est toujours valide.
    • L'user-agent du navigateur associé à la requête correspond à l'agent du navigateur associé à la session.
  9. Si les vérifications de l'étape précédente sont réussies, la requête est redirigée à l'aide de l'URI cible contenu dans l'URL. Il s'agit du même processus que pour la connexion intégrée avec connexion Looker.

  10. Cette requête est la redirection permettant de lancer le tableau de bord Looker. Cette requête contiendra le jeton de navigation en tant que paramètre.

  11. Avant l'exécution du point de terminaison, le serveur Looker recherche le jeton de navigation dans la requête. Si le serveur trouve le jeton, il vérifie les éléments suivants:

    • La session associée est toujours valide.
    • L'user-agent du navigateur associé à la requête correspond à l'agent du navigateur associé à la session.

    Si le jeton est valide, la session est restaurée pour la requête et la requête du tableau de bord s'exécute.

  12. Le code HTML permettant de charger le tableau de bord est renvoyé dans l'iFrame.

  13. L'interface utilisateur de Looker exécutée dans l'iFrame détermine que le code HTML du tableau de bord est une réponse d'intégration sans cookie. À ce stade, l'UI Looker envoie un message à l'application d'intégration pour demander les jetons récupérés à l'étape 6. L'UI attend ensuite de recevoir les jetons. Si les jetons ne sont pas reçus, un message s'affiche.

  14. L'application d'intégration envoie les jetons à l'iFrame intégrée Looker.

  15. Lorsque les jetons sont reçus, l'UI Looker exécutée dans l'iFrame lance le processus de rendu de l'objet de requête. Au cours de ce processus, l'UI effectue des appels d'API au serveur Looker. Le jeton d'API reçu à l'étape 15 est automatiquement injecté en tant qu'en-tête dans toutes les requêtes API.

  16. Avant l'exécution d'un point de terminaison, le serveur Looker recherche le jeton d'API dans la requête. Si le serveur trouve le jeton, il vérifie les éléments suivants:

    • La session associée est toujours valide.
    • L'user-agent du navigateur associé à la requête correspond à l'agent du navigateur associé à la session.

    Si la session est valide, elle est restaurée pour la requête, et la requête API s'exécute.

  17. Les données du tableau de bord sont renvoyées.

  18. Le tableau de bord s'affiche.

  19. L'utilisateur contrôle le tableau de bord.

Générer de nouveaux jetons

Le diagramme de séquence suivant illustre la génération de nouveaux jetons.

Diagramme de séquence illustrant la génération de nouveaux jetons.

  1. L'UI Looker exécutée dans l'iFrame intégrée surveille la valeur TTL des jetons d'intégration.
  2. Lorsque les jetons arrivent à expiration, l'UI Looker envoie un message de jeton d'actualisation au client de l'application d'intégration.
  3. Le client de l'application d'intégration demande ensuite de nouveaux jetons à un point de terminaison implémenté dans le serveur de l'application d'intégration. Le SDK d'ingestion Looker demande automatiquement de nouveaux jetons, mais l'URL du point de terminaison ou une fonction de rappel doit être fournie. Si la fonction de rappel est utilisée, elle appelle le serveur d'application d'intégration pour générer de nouveaux jetons. Sinon, le SDK d'intégration appelle l'URL du point de terminaison fournie.
  4. L'application d'intégration trouve l'session_reference_token associé à la session d'intégration. L'exemple fourni dans le dépôt Git du SDK Looker Embed utilise des cookies de session, mais un cache côté serveur distribué, Redis par exemple, peut également être utilisé.
  5. Le serveur d'application d'embedding appelle le serveur Looker avec une requête de génération de jetons. Cette requête nécessite également des jetons d'API et de navigation récents, en plus de l'user-agent du navigateur à l'origine de la requête.
  6. Le serveur Looker valide l'user-agent, le jeton de référence de session, le jeton de navigation et le jeton d'API. Si la requête est valide, de nouveaux jetons sont générés.
  7. Les jetons sont renvoyés au serveur d'application d'intégration appelant.
  8. Le serveur d'application d'intégration supprime le jeton de référence de session de la réponse et renvoie la réponse restante au client de l'application d'intégration.
  9. Le client de l'application d'intégration envoie les nouveaux jetons générés à l'UI Looker. Le SDK d'ingestion Looker s'en chargera automatiquement. Les clients d'application intégrés qui utilisent l'API windows.postMessage seront chargés d'envoyer les jetons. Une fois que l'UI Looker aura reçu les jetons, ils seront utilisés dans les appels d'API et les navigations de page suivants.

Implémenter l'intégration sans cookie de Looker

L'intégration sans cookie Looker peut être implémentée à l'aide du SDK d'ingestion Looker ou de l'API windows.postMessage. La méthode qui utilise le SDK d'intégration Looker est plus simple, mais un exemple montrant comment utiliser l'API windows.postMessage est également disponible. Vous trouverez des explications détaillées sur les deux implémentations dans le fichier README du SDK d'intégration de Looker. Le dépôt git du SDK Embed contient également des implémentations fonctionnelles.

Configurer l'instance Looker

L'intégration sans cookie présente des similitudes avec l'intégration avec signature de Looker. L'intégration sans cookie repose sur l'activation de l'option Intégrer l'authentification SSO. Toutefois, contrairement à l'intégration avec signature Looker, l'intégration sans cookie n'utilise pas le paramètre Secret d'intégration. L'intégration sans cookie utilise un jeton Web JSON (JWT) sous la forme d'un paramètre Secret d'intégration du jeton JWT, qui peut être défini ou réinitialisé sur la page Intégration, dans la section Plate-forme du menu Administration.

Il n'est pas nécessaire de définir le secret JWT, car la toute première tentative de création d'une session d'intégration sans cookie crée le JWT. Évitez de réinitialiser ce jeton, car cela invalidera toutes les sessions d'intégration sans cookie actives.

Contrairement au secret d'intégration, le secret JWT d'intégration n'est jamais exposé, car il n'est utilisé qu'en interne sur le serveur Looker.

Implémentation du client d'application

Cette section inclut des exemples d'implémentation de l'intégration sans cookie dans le client de l'application et contient les sous-sections suivantes:

Installer ou mettre à jour le SDK d'ingestion Looker

Les versions suivantes du SDK Looker sont requises pour utiliser l'intégration sans cookie:

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

Utiliser le SDK d'ingestion Looker

Une nouvelle méthode d'initialisation a été ajoutée au SDK Embed pour lancer la session sans cookie. Cette méthode accepte deux chaînes d'URL ou deux fonctions de rappel. Les chaînes d'URL doivent faire référence aux points de terminaison du serveur d'application d'intégration. Pour en savoir plus sur l'implémentation de ces points de terminaison sur le serveur d'applications, consultez la section Implémentation du serveur d'applications de ce document.

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

L'exemple suivant montre comment les rappels sont utilisés. Les rappels ne doivent être utilisés que lorsque l'application cliente d'intégration doit connaître l'état de la session d'intégration Looker. Vous pouvez également utiliser l'événement session:status, ce qui vous évite d'utiliser des rappels avec le SDK Embed.

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 (): Promise<LookerEmbedCookielessSessionData> => {
    const { api_token, navigation_token } = getApplicationTokens() || {}
    const resp = await fetch('/generate-embed-tokens', {
      method: 'PUT',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ api_token, navigation_token }),
    })
    if (!resp.ok) {
      if (resp.status === 400) {
        return { session_reference_token_ttl: 0 }
      }
      console.error('generate-embed-tokens failed', { resp })
      throw new Error(
        `generate-embed-tokens failed: ${resp.status} ${resp.statusText}`
      )
    }
    return (await resp.json()) as LookerEmbedCookielessSessionData
  }


    LookerEmbedSDK.initCookieless(
      runtimeConfig.lookerHost,
      acquireEmbedSessionCallback,
      generateEmbedTokensCallback
    )

Utiliser l'API Looker windows.postMessage

Vous pouvez consulter un exemple détaillé de l'utilisation de l'API windows.postMessage dans les fichiers message_example.ts et message_utils.ts du dépôt Git du SDK Embed. Vous trouverez ci-dessous les points forts de l'exemple.

L'exemple suivant montre comment créer l'URL de l'iframe. La fonction de rappel est identique à l'exemple acquireEmbedSessionCallback vu précédemment.

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

L'exemple suivant montre comment écouter les requêtes de jetons, générer de nouveaux jetons et les envoyer à Looker. La fonction de rappel est identique à celle de l'exemple generateEmbedTokensCallback précédent.

      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
  }

Implémentation du serveur d'applications

Cette section inclut des exemples d'implémentation de l'intégration sans cookie dans le serveur d'application et contient les sous-sections suivantes:

Implémentation de base

L'application d'intégration doit implémenter deux points de terminaison côté serveur qui appelleront les points de terminaison Looker. Cela permet de s'assurer que le jeton de référence de session reste sécurisé. Voici les points de terminaison:

  1. Acquérir une session : si un jeton de référence de session existe déjà et est toujours actif, les requêtes de session rejoindront la session existante. La session d'acquisition est appelée lorsqu'un iframe est créé.
  2. Générer des jetons : Looker déclenche régulièrement des appels à ce point de terminaison.

Acquérir une session

Cet exemple en TypeScript utilise la session pour enregistrer ou restaurer le jeton de référence de session. Le point de terminaison n'a pas besoin d'être implémenté en 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
  }
}

À partir de Looker 23.8, le domaine d'intégration peut être inclus lorsque la session sans cookie est acquise. Il s'agit d'une alternative à l'ajout du domaine d'intégration à l'aide du panneau Administration > Intégration de Looker. Looker enregistre le domaine d'intégration dans la base de données interne de Looker. Il ne s'affiche donc pas dans le panneau Administration > Intégrer. Le domaine d'intégration est associé à la session sans cookie et n'existe que pendant la durée de la session. Consultez les bonnes pratiques de sécurité si vous décidez de profiter de cette fonctionnalité.

Générer des jetons

Cet exemple en TypeScript utilise la session pour enregistrer ou restaurer le jeton de référence de session. Le point de terminaison n'a pas besoin d'être implémenté en TypeScript.

Il est important que vous sachiez gérer les réponses 400, qui se produisent lorsque les jetons ne sont pas valides. Une réponse 400 ne devrait pas être renvoyée, mais si c'est le cas, il est recommandé de mettre fin à la session d'intégration Looker. Vous pouvez mettre fin à la session d'intégration Looker en détruisant l'iFrame d'intégration ou en définissant la valeur session_reference_token_ttl sur zéro dans le message session:tokens. Si vous définissez la valeur session_reference_token_ttl sur zéro, l'iFrame Looker affiche une boîte de dialogue indiquant que la session a expiré.

Aucune réponse 400 n'est renvoyée lorsque la session d'intégration expire. Si la session d'intégration a expiré, une réponse 200 est renvoyée, avec la valeur session_reference_token_ttl définie sur zéro.

  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')) {
      // Currently the Looker UI does not know how to handle bad
      // tokens. This should not 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
  }

Observations relatives à la mise en œuvre

L'application d'intégration doit suivre le jeton de référence de session et le sécuriser. Ce jeton doit être associé à l'utilisateur de l'application intégrée. Le jeton d'application d'intégration peut être stocké de l'une des manières suivantes:

  • Dans la session de l'utilisateur de l'application intégrée
  • Dans un cache côté serveur disponible dans un environnement en cluster
  • Dans une table de base de données associée à l'utilisateur

Si la session est stockée sous forme de cookie, celui-ci doit être chiffré. L'exemple du dépôt du SDK d'intégration utilise un cookie de session pour stocker le jeton de référence de session.

Lorsque la session d'intégration Looker expire, une boîte de dialogue s'affiche dans l'iFrame intégré. À ce stade, l'utilisateur ne peut rien faire dans l'instance intégrée. Dans ce cas, les événements session:status sont générés, ce qui permet à l'application d'intégration de détecter l'état actuel de l'application Looker intégrée et d'effectuer une action.

Une application d'intégration peut détecter si la session d'intégration a expiré en vérifiant si la valeur session_reference_token_ttl renvoyée par le point de terminaison generate_tokens est nulle. Si la valeur est nulle, la session d'intégration a expiré. Envisagez d'utiliser une fonction de rappel pour générer des jetons lorsque l'intégration sans cookie est en cours d'initialisation. La fonction de rappel peut ensuite déterminer si la session d'intégration a expiré et supprimer l'iframe intégrée au lieu d'utiliser la boîte de dialogue par défaut d'expiration de la session d'intégration.

Exécuter l'exemple d'intégration sans cookie Looker

Le dépôt du SDK d'intégration contient un serveur et un client node.js Express simples, écrits en TypeScript, qui implémentent une application d'intégration simple. Les exemples présentés précédemment sont issus de cette implémentation. Le code suivant suppose que votre instance Looker a été configurée pour utiliser l'intégration sans cookie, comme décrit précédemment.

Vous pouvez exécuter le serveur comme suit:

  1. Cloner le dépôt du SDK d'ingestion : git clone git@github.com:looker-open-source/embed-sdk.git
  2. Changer de répertoire : cd embed-sdk
  3. Installer les dépendances : npm install
  4. Configurez le serveur, comme indiqué dans la section Configurer le serveur de ce document.
  5. Exécuter le serveur : npm run server

Configurer le serveur

Créez un fichier .env dans la racine du dépôt cloné (il est inclus dans .gitignore).

Le format est le suivant :

LOOKER_EMBED_HOST=your-looker-instance-url.com.
LOOKER_EMBED_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