Autenticação da API Looker usando o OAuth

O Looker usa o OAuth para permitir que os aplicativos cliente OAuth se autentiquem na API Looker sem expor IDs do cliente e chaves secretas do cliente ao navegador que está executando o aplicativo cliente OAuth.

Os aplicativos da Web que usam o OAuth precisam atender aos seguintes requisitos:

  • A autenticação usando OAuth está disponível apenas com a API Looker 4.0.
  • Os aplicativos cliente OAuth precisam ser registrados no Looker usando a API antes que os usuários do aplicativo possam se autenticar no Looker.
  • Os aplicativos cliente precisam usar HTTPS em todas as solicitações para a API Looker. Os aplicativos clientes que querem usar as APIs SubtleCrypto fornecidas pelo navegador precisam ser hospedados em HTTPS.

Suporte ao CORS da API Looker

A API Looker pode ser chamada no navegador e em várias origens usando o protocolo de Compartilhamento de recursos entre origens (CORS). O suporte ao CORS do Looker tem os seguintes requisitos:

  • Somente as origens listadas na lista de permissões de domínios incorporados podem chamar a API usando CORS.

  • Somente tokens de acesso obtidos do OAuth ou da chamada do endpoint de API /login podem ser usados para fazer chamadas à API Looker usando o CORS.

Visão geral da autenticação OAuth

Confira uma visão geral do processo de autenticação OAuth:

  1. Registre o aplicativo cliente OAuth na instância do Looker.
  2. Adicione a origem do aplicativo cliente OAuth à lista de permissões de domínios incorporados para a chamada de API de troca de código e todas as chamadas de API CORS subsequentes.

  3. Redirecione o URL do navegador para o endpoint /auth no nome do host da interface do Looker (não no nome do host da API Looker) quando o aplicativo cliente OAuth tentar autenticar um usuário. Por exemplo, https://instance_name.looker.com.

  4. Se o usuário for autenticado e fizer login no Looker, o Looker vai retornar um redirecionamento do OAuth para o aplicativo cliente do OAuth imediatamente. Se o usuário ainda não tiver feito login no Looker no dispositivo e no navegador, a tela de login do Looker será exibida e o usuário precisará fazer login na conta de usuário do Looker usando o protocolo de autenticação normal.

  5. Usando o código de autorização retornado no redirecionamento do OAuth, seu aplicativo cliente OAuth deve fazer uma chamada para o endpoint /token no nome do host da API Looker, por exemplo, https://instance_name.looker.com:19999. O nome do host da API pode ser igual ou diferente do nome do host da interface do Looker. O endpoint /token existe apenas no host da API Looker, e o endpoint /auth existe apenas no host da interface do Looker.

  6. Se o código de autorização transmitido ao endpoint /token for válido, o Looker vai retornar uma API access_token ativada para solicitações de API CORS do domínio do aplicativo cliente OAuth.

Como registrar um aplicativo cliente OAuth

Todo aplicativo cliente OAuth que tenta se autenticar na API Looker usando OAuth precisa ser registrado na instância do Looker antes que o Looker autorize o acesso.

Os administradores do Looker podem registrar e gerenciar aplicativos cliente OAuth personalizados diretamente no painel Administrador do Looker na página Gerenciar clientes OAuth (Administrador > Autenticação > Gerenciar clientes OAuth). Essa interface permite que os administradores realizem as seguintes tarefas:

  • Configure um ou mais URIs de redirecionamento autorizados para que o aplicativo seja compatível com vários ambientes e portas.
  • Restringir o acesso de autorização aos membros de um grupo de usuários específico do Looker (Restringir ao ID do grupo).
  • Ver, editar, ativar, desativar ou excluir aplicativos personalizados registrados.

Para instruções guiadas sobre como registrar clientes personalizados no painel de administrador, consulte a página de documentação Configurações de administrador: gerenciar clientes OAuth.

Registro programático usando a API

Como alternativa, os administradores podem registrar um aplicativo cliente OAuth de maneira programática chamando o endpoint de registro do app OAuth diretamente ou executando-o no APIs Explorer do Looker. Os parâmetros incluem:

  • client_guid: um ID de string exclusivo para o aplicativo (não pode começar com com.looker.).
  • redirect_uris: uma matriz de URIs de callback autorizados em que o aplicativo vai receber o redirecionamento do OAuth e o código de autorização.
  • display_name: o nome do aplicativo que é exibido aos usuários.
  • description: uma descrição do aplicativo cliente OAuth.
  • group_id (opcional): o ID numérico de um grupo do Looker para restringir o acesso.

Como fazer login de usuário usando o OAuth

  1. Direcione o usuário para o endpoint /auth no host da UI. Exemplo:

    async function oauth_login() {
      const code_verifier = secure_random(32)
      const code_challenge = await sha256_hash(code_verifier)
      const params = {
        response_type: 'code',
        client_id: '123456',
        redirect_uri: 'https://mywebapp.com:3000/authenticated',
        scope: 'cors_api',
        state: '1235813',
        code_challenge_method: 'S256',
        code_challenge: code_challenge,
      }
      const url = `${base_url}?${new URLSearchParams(params).toString()}` // Replace base_url with your full Looker instance's UI host URL, plus the `/auth` endpoint.
      log(url)
    
      // Stash the code verifier we created in sessionStorage, which
      // will survive page loads caused by login redirects
      // The code verifier value is needed after the login redirect
      // to redeem the auth_code received for an access_token
      //
      sessionStorage.setItem('code_verifier', code_verifier)
    
      document.location = url
    }
    
    function array_to_hex(array) {
      return Array.from(array).map(b => b.toString(16).padStart(2,'0')).join('')
    }
    
    function secure_random(byte_count) {
      const array = new Uint8Array(byte_count);
      crypto.getRandomValues(array);
      return array_to_hex(array)
    }
    
    async function sha256_hash(message) {
      const msgUint8 = new TextEncoder().encode(message)
      const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8)
      return base64.urlEncode(hashBuffer))  // Refers to the implementation of base64.encode stored at https://gist.github.com/jhurliman/1250118
    }
    

    O Looker vai tentar autenticar o usuário usando o sistema de autenticação para o qual a instância do Looker está configurada.

    • Se o usuário já tiver feito login no Looker no navegador atual (ou seja, houver um estado de cookie de login ativo), ele não precisará inserir as credenciais de login.
    • Se esta for a primeira vez que o usuário faz login usando esse aplicativo cliente OAuth, o Looker vai mostrar uma página de declaração e confirmação para que o usuário confirme e aceite. O texto do parâmetro description usado quando o aplicativo foi registrado será exibido. A descrição precisa indicar o que o aplicativo pretende fazer com a conta do Looker do usuário. Quando o usuário clicar em aceitar, a página vai redirecionar para o aplicativo redirect_uri.
    • Se o usuário já tiver feito login no Looker no navegador atual e já tiver confirmado a página de declaração, o login do OAuth será instantâneo, sem interrupção visual.
  2. A API Looker vai retornar um redirecionamento OAuth para o aplicativo cliente OAuth. Salve o código de autorização listado no parâmetro de URI. Veja a seguir um exemplo de URI de redirecionamento do OAuth:

    https://mywebapp.com:3000/authenticated?&code=asdfasdfassdf&state=...
    

    O código de autorização é mostrado após &code= no URI. Neste exemplo, o código de autorização é asdfasdfassdf.

  3. Faça uma solicitação da Web para o endpoint /token na API Looker, transmitindo o código de autorização e as informações do aplicativo. Exemplo:

    async function redeem_auth_code(response_str) {
      const params = new URLSearchParams(response_str)
      const auth_code = params.get('code')
    
      if (!auth_code) {
        log('ERROR: No authorization code in response')
        return
      }
      log(`auth code received: ${auth_code}`)
      log(`state: ${params.get('state')}`)
    
      const code_verifier = sessionStorage.getItem('code_verifier')
      if (!code_verifier) {
        log('ERROR: Missing code_verifier in session storage')
        return
      }
      sessionStorage.removeItem('code_verifier')
      const response = await
      fetch('https://mycompany.looker.com:19999/api/token', {  // This is the URL of your Looker instance's API web service
        method: 'POST',
        mode: 'cors',    // This line is required so that the browser will attempt a CORS request.
        body: stringify({
          grant_type: 'authorization_code',
          client_id: '123456',
          redirect_uri: 'https://mywebapp.com:3000/authenticated',
          code: auth_code,
          code_verifier: code_verifier,
        }),
        headers: {
          'x-looker-appid': 'Web App Auth & CORS API Demo', // This header is optional.
          'Content-Type': 'application/json;charset=UTF-8'  // This header is required.
        },
      }).catch((error) => {
        log(`Error: ${error.message}`)
      })
    
      const info = await response.json()
      log(`/api/token response: ${stringify(info)}`)
    
      // Store the access_token and other info,
      // which in this example is done in sessionStorage
    
      const expires_at = new Date(Date.now() + (info.expires_in * 1000))
      info.expires_at = expires_at
      log(`Access token expires at ${expires_at.toLocaleTimeString()} local time.`)
      sessionStorage.setItem('access_info', stringify(info))
      access_info = info
    }
    

    Uma resposta bem-sucedida vai fornecer ao aplicativo cliente OAuth um access_token da API. A resposta também vai conter um refresh_token, que pode ser usado mais tarde para receber um novo access_token sem interação do usuário. Um refresh_token tem um ciclo de vida de um mês. Armazene o refresh_token com segurança.

    Todos os tokens nesse sistema podem ser revogados pelo administrador do Looker a qualquer momento.