Implementazione della sicurezza a livello di riga per i contenuti Looker incorporati

Scritto da Christopher Seymour, Sr. Data Analyst e Dean Hicks, Developer Relations Engineer

Introduzione

La funzionalità di incorporamento di Looker è una delle più potenti e preziose del prodotto Looker. Se stai leggendo questa guida, è probabile che tu stia già incorporando contenuti di Looker nella tua applicazione o che intendi farlo nel prossimo futuro.

Questa guida ha lo scopo di aiutarti a comprendere meglio il design della funzionalità di incorporamento di Looker per creare un'applicazione potente e sicura per la distribuzione dei dati ai tuoi utenti. Poiché l'approfondimento sull'argomento è un po' lungo, tieni presente che questa guida non deve essere una soluzione rapida per risolvere un problema semplice, ma piuttosto un componente di base per aiutarti a gestire meglio l'intero caso d'uso di incorporamento di Looker.

Panoramica del caso d'uso

Questa guida descrive un caso d'uso comune in cui la tua azienda incorpora contenuti Looker all'interno del tuo prodotto.

Per questo caso d'uso dell'incorporamento firmato, supponiamo di essere l'amministratore dell'istanza di Looker. Lavori con due tipi di utenti incorporati: clienti (o "utenti del brand"), che dovrebbero poter accedere solo ai dati relativi alla loro azienda, e proprietari dell'account, che potranno accedere ai dati di più clienti specifici. Hai una dashboard con alcuni riquadri che mostri a ogni cliente che utilizza il tuo prodotto, ma è necessario che la dashboard venga filtrata automaticamente per ogni cliente, in modo che le dashboard mostrino solo i dati specifici di quel cliente. Gli esempi riportati in questo documento utilizzano due aziende fittizie: Hooli e Pied Piper.

Hai una tabella denominata prodotti, che mostra alcune metriche relative ai prodotti di brand diversi. Ogni brand corrisponde a un diverso utente di incorporamento (con un external_user_id diverso) nell'applicazione di incorporamento firmata. Dal momento che ogni utente incorporato dovrebbe poter vedere solo i dati relativi al proprio brand, hai una semplice esplorazione che utilizza un filtro di accesso su un attributo utente brand:

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

Hai una dashboard semplice basata su questa esplorazione e con due riquadri: uno mostra il nome del brand e l'altro il numero di prodotti per quel brand.

Puoi utilizzare l'endpoint create_sso_embed_url per generare URL di incorporamento di questa dashboard per ogni utente incorporato. In questo esempio vengono utilizzati due brand: Pifferaio magico e Hooli. Ecco il corpo della richiesta che utilizzi nella chiamata create_sso_embed_url per Pifferaio magico, con 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"}
}

L'URL che hai generato per Pied Piper mostra la dashboard in questo modo:

Ecco il corpo della richiesta utilizzato nella chiamata create_sso_embed_url per Hooli, con 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"}
}

L'URL generato per Hooli mostra la dashboard in questo modo:

Voilà! La dashboard viene filtrata in base al valore di ciascun utente incorporato per l'attributo utente brand.

Approfondimento

Molto bello. Ma cosa succede se volessi concedere a un proprietario dell'account l'accesso a più brand? Come faccio ad assicurarmi che i miei dati vengano visti solo dagli utenti pertinenti?

Buone notizie. La funzionalità di incorporamento firmata di Looker è stata progettata per consentire agli sviluppatori di creare esperienze di dati efficaci e su misura per gli utenti, garantendo al contempo il mantenimento della governance dei dati definita dal modello dei dati e dai criteri di accesso ai contenuti.

Assicurarsi che la governance dei dati sia ermetica è fondamentale per garantire un'esperienza sui dati efficace. Continua a leggere per esplorare alcuni concetti e best practice che puoi utilizzare per progettare l'esperienza più adatta a te. La prima è una breve panoramica del funzionamento di tutto questo.

Informazioni di base sull'incorporamento firmato di Looker

È importante tenere presente che l'autenticazione e la gestione degli utenti di Looker nel contesto di incorporamento funzionano fondamentalmente allo stesso modo che nel contesto non incorporato e sostanzialmente allo stesso modo della maggior parte delle altre applicazioni web.

Questo può creare confusione nel contesto di incorporamento con firma di Looker, perché il passaggio di autenticazione firmato, le impostazioni utente e la dashboard stessa sono combinati in un unico URL lungo e complesso. Tuttavia, quell'URL viene utilizzato per stabilire la sessione, il che continua a essere valido anche dopo che l'URL è stato abbreviato. Tenere a mente questo concetto sarà determinante per il tuo successo nella creazione di fantastiche esperienze sui dati.

Struttura dell'URL incorporato firmato

Ecco uno degli URL di autenticazione da incorporare firmati generati dalla chiamata create_sso_embed_url con il corpo della richiesta per 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

Ecco lo stesso URL decodificato e suddiviso in singole righe:

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 accedi a questo URL, si verificano alcune cose:

  1. Looker cerca un account utente esistente con external_user_id = pied_piper. Se non ne esiste nessuno, Looker crea un nuovo account utente con quel external_user_id.

  2. I dettagli dell'account utente esistente, inclusi autorizzazioni, modelli, gruppi (se specificati) e valori degli attributi utente (se specificati) vengono sovrascritti con i dettagli dell'account specificati nell'URL.

  3. Looker autentica l'utente e stabilisce una sessione per quell'utente memorizzando un cookie di sessione nel browser.

  4. Looker reindirizza quindi all'URL di destinazione o all'URL di reindirizzamento specificato nella chiamata create_sso_embed_url:

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

    Puoi vedere questo URL di reindirizzamento come un URL relativo codificato nell'URL di incorporamento originale firmato:

    %2Fembed%2Fdashboards%2F17

Sebbene i passaggi da 1 a 3 vengano eseguiti automaticamente in background e l'utente finale vede solo il risultato finale (la dashboard stessa), questi passaggi sono fondamentalmente gli stessi dei passaggi con cui un utente Looker normale e non incorporato autentica. Supponi di volere che un utente acceda con le credenziali utente e password. La procedura potrebbe essere simile alla seguente:

  1. In qualità di amministratore di Looker, vai al riquadro Amministratore - Utenti e utilizza la barra di ricerca per verificare se esiste già un account utente per l'utente in questione. In caso contrario, crea un nuovo account utente.

  2. In qualità di amministratore di Looker, fai clic su Modifica accanto all'utente nel riquadro Amministratore - Utenti ed esegui il provisioning dell'utente con autorizzazioni, modelli, gruppi, valori degli attributi utente e altri valori.

  3. L'utente accede alla pagina di accesso all'indirizzo https://mylookerinstance.cloud.looker.com/login e inserisce nome utente e password. Looker autentica l'utente e stabilisce una sessione per quell'utente memorizzando un cookie di sessione nel browser.

  4. Looker reindirizza quindi alla pagina di destinazione (di solito https://mylookerinstance.cloud.looker.com/browse).

Tieni presente che il cookie di sessione verrà applicato a tutte le schede della finestra del browser. Se l'utente inizia il giorno https://mylookerinstance.cloud.looker.com/browse, apre una nuova scheda del browser e apre una pagina a cui è consentito l'accesso, la pagina verrà caricata come previsto utilizzando il cookie di sessione già impostato nella scheda originale del browser.

Lo stesso vale per gli utenti incorporati. Le pagine a cui possono accedere nell'interfaccia utente degli utenti incorporati sono leggermente più limitate: possono accedere solo agli URL di Look, dashboard ed esplorazioni con il prefisso /embed. Possono comunque accedere manualmente alle dashboard a cui possono accedere con i dettagli del loro account utente. Supponiamo che l'URL incorporato originale firmato ti reindirizzi a https://mylookerinstance.cloud.looker.com/embed/dashboards/17 in una scheda del browser. Dopodiché apri una nuova scheda del browser e carichi una dashboard di incorporamento diversa che si trova nella stessa cartella (e che quindi ha le stesse restrizioni di accesso): https://mylookerinstance.cloud.looker.com/embed/dashboards/19.

Anche se l'URL di reindirizzamento specificato nell'URL di incorporamento originale firmato era per la dashboard 17, puoi notare che la dashboard 19 viene caricata come previsto se inserisci manualmente l'URL in una scheda del browser. Tieni presente che non era necessario un altro URL incorporato firmato per caricare una dashboard diversa.

L'analisi fondamentale qui è che tutti i dettagli dell'account utente stabiliti nell'URL (autorizzazioni, attributi utente e così via) vengono applicati all'intera sessione utente, non solo alla dashboard specifica specificata nell'URL firmato originale. In altre parole, come suggerisce il nome, gli attributi utente sono una funzionalità dell'utente, non una funzionalità della dashboard, e dovrebbero essere utilizzati per determinare i livelli di accesso di un utente specifico nell'intera applicazione, non solo in una scheda specifica.

Il caso d'uso del proprietario dell'account

Come per qualsiasi soluzione personalizzabile, esistono alcuni approcci che dovresti evitare. Tenendo conto di questo, considera di avere anche proprietari dell'account che possono possedere o gestire più brand. In questo esempio, il proprietario di un account gestisce sia il brand Pifferaio magico che il brand Hooli. Di conseguenza, l'app genera gli URL per entrambi i external_user_ids utilizzando gli stessi input nella chiamata create_sso_embed_url mostrata in precedenza e crea una nuova scheda nell'app per caricare ogni dashboard a cui il proprietario dell'account vuole accedere. Spesso gli sviluppatori implementano soluzioni come questa, causando un flusso di lavoro non corretto per l'utente:

  1. Vai alla scheda della dashboard Pied Piper.
  2. Vai alla scheda della dashboard Hooli.
  3. Torna alla scheda della dashboard Pied Piper.
  4. Premi il pulsante Ricarica nella dashboard Pied Piper.

...la dashboard Pifferaio magico mostra i dati di Hooli.

Puoi provare un approccio simile, ma utilizzare lo stesso external_user_id test_user per entrambe le chiamate create_sso_embed_url:

{
  "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"}
}

{
  "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":"Hooli"}
}

Ma il comportamento è esattamente lo stesso: una volta ricaricata la scheda con il pannello Pied Piper, vengono mostrati i dati relativi a Hooli.

Che succede qui? Come faccio ad assicurarmi che la dashboard di ogni brand mostri solo i dati relativi a quel brand?

Lo stesso approccio, da un punto di vista non basato sull'incorporamento

Come discusso nella sezione precedente, le sessioni utente di incorporamento firmate funzionano fondamentalmente allo stesso modo delle normali sessioni utente Looker non incorporate. Di conseguenza, può essere utile riformulare l'approccio problematico descritto in precedenza nel contesto di una sessione utente Looker regolare e non incorporata e suddividere questi passaggi per capire come implementare questa soluzione in modo più solido. Ecco come sarebbe il flusso di lavoro se fornisci istruzioni a un utente BI standard che ha accesso all'UI di Looker:

  1. Puoi creare due diversi account utente nella pagina Amministrazione - Utenti.
    1. Nella pagina di modifica del primo account utente, imposta il valore dell'attributo utente brand su pied_piper.
    2. Nella pagina di modifica del secondo account utente, imposta il valore dell'attributo utente brand su hooli.
  2. Invia email per la creazione di entrambi gli account utente al proprietario dell'account.
  3. Il proprietario dell'account configura credenziali email e password separate per ogni account.
  4. Devi fornire al proprietario dell'account il link alla dashboard. (https://mylookerinstance.cloud.looker.com/dashboards/17) e informalo che, per poter passare da un brand all'altro, deve tornare alla pagina di accesso in un'altra scheda e inserire le credenziali email e password dell'altro account utente, quindi caricare di nuovo la dashboard in quella scheda.

Il proprietario dell'account segue le istruzioni. Tuttavia, dopo aver inserito il nome utente e la password dell'account utente Hooli nella seconda scheda del browser e aver tornato alla prima scheda in cui la dashboard Pied Piper era già caricata, il proprietario dell'account fa clic sul pulsante Ricarica. Con grande sorpresa del proprietario dell'account, la dashboard mostra i dati di Hooli. Questo non dovrebbe sorprendere, dato che lo stesso scenario si è già verificato nel contesto dell'incorporamento.

Puoi suddividere rapidamente la seconda implementazione (utilizzando lo stesso external_user_id test_user con insiemi diversi di attributi utente) nello stesso modo. L'equivalente UI di quel flusso di lavoro sarebbe simile a questo:

  1. Creare un account utente per il proprietario dell'account.
  2. Imposta pied_piper come valore dell'attributo brand per quell'account utente.
  3. Dici al proprietario dell'account che per passare dalla dashboard al Pied Piper a Hooli deve contattarti in modo che tu possa andare alla pagina di modifica dell'account utente in questione e cambiare il valore dell'attributo brand da pied_piper a hooli durante la sessione.
  4. Dopo aver modificato l'attributo utente, l'utente può caricare di nuovo la dashboard in una nuova scheda per visualizzare i dati di Hooli.

A questo punto potresti pensare:

Aspetta... sembra che ci sia moltissimo lavoro da fare. Non c'è un modo per fornire loro un singolo account utente e consentire loro di filtrare i dati sulla dashboard in modo discreto per ogni brand?

Di sicuro! Ciò che questi scenari aiutano a illustrare è un principio già banale nel contesto non incorporato, ma che può essere oscurato dalle astrazioni del contesto di incorporamento: un singolo utente umano deve essere associato a un singolo account utente Looker con un singolo insieme di valori degli attributi utente. Questo concetto è più chiaro anche nella spiegazione di external_user_id nella documentazione relativa all'incorporamento firmato.

Looker utilizza external_user_id per distinguere gli utenti incorporati con firma, perciò a ogni utente deve essere assegnato un ID univoco.

Puoi creare un external_user_id per un utente con qualsiasi stringa tu voglia, purché sia univoca per l'utente. Ogni ID è associato a un insieme di autorizzazioni, attributi utente e modelli. Un singolo browser può supportare solo un external_user_id, o sessione utente, alla volta. Non è possibile apportare modifiche alle autorizzazioni o agli attributi utente di un utente durante una sessione.

Applica queste best practice

Applicando questi principi al nostro esempio, avrai bisogno di un singolo valore di attributo utente che dia l'accesso a TUTTI i dati a cui il proprietario dell'account deve avere accesso nell'applicazione. Puoi farlo utilizzando un valore separato da virgole per l'attributo 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"}
}

Affinché questa sintassi funzioni, devi assicurarti che l'attributo utente sia impostato su Filtro stringa (avanzato):

Tieni presente che puoi comunque modificare l'insieme di attributi utente per un utente se cambia qualcosa nei suoi livelli di accesso ai dati. Ad esempio, se il proprietario dell'account si assume la proprietà di un terzo brand, puoi aggiungerlo all'elenco separato da virgole specificato per l'attributo utente brand. In questo modo, le modifiche verranno applicate quando escono e riaccedi.

Filtro dei risultati della dashboard

Ho capito che gli attributi utente devono specificare tutti i dati a cui un utente può accedere nell'applicazione. Se invece specifico gli attributi utente in questo modo, nella mia dashboard verranno visualizzati i dati di tutti i brand interessati. Come faccio a restringere i risultati di una determinata dashboard a un brand specifico?

Il modo corretto per filtrare una determinata dashboard è utilizzare i normali filtri della dashboard. (Questo potrebbe sembrare ovvio ora, ma abbiamo visto che alcune persone rimangono bloccate sugli attributi utente come unico modo per applicare filtri nel contesto di incorporamento, forse perché user_attributes è un parametro nell'URL di incorporamento firmato, al contrario dei filtri.)

Assicurati di richiedere un valore di filtro e utilizza una delle opzioni di controllo Selezione singola, come l'elenco a discesa:

Assicurati che il filtro sia applicato al campo corretto su tutti i riquadri necessari:

Ora il proprietario dell'account può scegliere tra questi due valori (e solo questi due), poiché le opzioni disponibili nel menu a discesa sono limitate dagli attributi utente:

Precompilazione dei filtri della dashboard

Ok, ora la dashboard può essere filtrata in base a un brand specifico, ma voglio che il valore del filtro sia già impostato su un brand specifico quando l'utente carica la dashboard per quel brand nella mia app.

Anche in questo caso, è utile riflettere su come funziona questa procedura nel contesto non incorporato. Come si invia a qualcuno un link a una dashboard a cui è già applicato un valore di filtro specifico? Come avrai notato, quando selezioni un valore di filtro, questo viene visualizzato nell'URL della dashboard:

Includi quella parte dell'URL in target_url per la chiamata 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 usi l'SDK incorporato, puoi usare withFilters per specificare i filtri iniziali da applicare ai contenuti incorporati:

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

Se utilizzi uno script personalizzato, accertati di aggiungere il filtro all'URL prima che il percorso venga codificato. Alcuni valori potrebbero essere già codificati nella stringa del filtro (ad esempio, c'è uno spazio codificato come + in ?Brand=Pied+Piper), pertanto quei valori verranno codificati due volte nell'URL finale. Dai uno sguardo alla sezione "SO incorporata dashboard - set dashboard dashboard as part of URL?": un post della scheda Community di Looker per approfondire queste sfumature. Se continui ad avere problemi con l'applicazione dei filtri, anche i post della scheda Community sono un ottimo posto per aggiungere domande.

I filtri della dashboard verranno nascosti

Ok, vedo come impostare i filtri iniziali sulle mie dashboard, ma non voglio neanche che il proprietario dell'account modifichi i filtri della dashboard da solo. Il valore del filtro deve essere determinato SOLO dalla dashboard a cui il proprietario dell'account ha visitato la mia app. Come faccio a nascondere i filtri della dashboard?

Per farlo, puoi utilizzare dei temi. I temi sono una funzionalità a pagamento, perciò se non hai già abilitato questa funzionalità sulla tua istanza di Looker, contatta il tuo team di vendita di Looker per attivarla.

Una volta attivata la funzionalità, vai alla sezione Controlli della dashboard della pagina Amministrazione - Temi, dove puoi cancellare l'opzione Visualizza barra dei filtri:

Dopodiché puoi impostare il tema come predefinito o applicarlo nell'URL delle tue dashboard specifiche. Anche in questo caso, andremo a target_url della chiamata 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"}
}

Trovi maggiori informazioni su come nascondere i filtri della dashboard di incorporamento, inclusi alcuni snippet di codice SDK incorporati, in questo tutorial di YouTube, Incorporare Looker con filtri personalizzati.

Il risultato finale dovrebbe sembrare identico all'esperienza utente della domanda originale:

Ora, però, poiché i valori dei filtri sono codificati nei rispettivi URL di destinazione incorporati nell'app, la dashboard di ogni brand mostrerà sempre la dashboard filtrata in base al brand corretto anche quando passi da una scheda all'altra.

Eseguire il comando sudo come altri utenti

Ora l'esperienza utente sembra molto simile a quella che avevo previsto inizialmente. Tuttavia, nel mio caso d'uso, il proprietario dell'account ha autorizzazioni e altre impostazioni utente diverse che i singoli utenti con external_user_id=pied_piper e external_user_id=hooli non hanno, il che porta a diverse opzioni disponibili nell'interfaccia utente e a un'esperienza utente complessiva leggermente diversa. Voglio che il proprietario dell'account veda tutto esattamente come vedono pied_piper e pied_piper gli utenti, come se il proprietario dell'account avesse effettivamente eseguito l'accesso come quegli utenti. Come posso fare?

Ciò che stai chiedendo si chiama "sudo". Se vuoi che il proprietario dell'account possa "sudo" per ogni singolo utente del brand, puoi creare una funzione sudo simile nella tua app che caricherà gli URL di incorporamento per external_user_id=pied_piper quando il proprietario dell'account esegue il comando sudo come utente di Pied Piper e gli URL per external_user_id=hooli quando il proprietario dell'account esegue il sudo come utente Hooli. Puoi anche utilizzare l'endpoint API di login_user per sudo come utente del brand con l'API se la tua app utilizza l'API.

Tuttavia, se pensi di nuovo al contesto non incorporato: nella pagina Amministrazione - Utenti, non puoi eseguire contemporaneamente il sudo come più utenti non incorporati in più schede: la sessione sudo verrà applicata all'intera finestra del browser, proprio come tutte le altre sessioni utente. Di conseguenza, dovresti progettare sudo in modo che lo sudo sia un solo utente alla volta. E, se ci pensiamo, questo design è più coerente con la riproduzione perfetta dell'esperienza degli utenti che state creando. Ad esempio, l'utente pied_piper ha accesso solo alla dashboard Pied Piper e non può aprire altre dashboard in schede aggiuntive. Di conseguenza, non dovresti essere in grado di aprire dashboard diverse in schede diverse quando esegui l'esecuzione di sudo come utente.

Conclusione

Ci auguriamo che questa guida ti sia stata utile e che tu ti senta preparato per procedere con la creazione dei tuoi contenuti incorporati firmati Looker. Lavoriamo costantemente per rendere Looker l'offerta di analisi dei dati incorporata più flessibile e solida e vorremmo ricevere il tuo feedback. Se hai domande o vuoi scoprire di più, puoi interagire con noi nella community di Looker e partecipare agli eventi della nostra community.