Autenticação da API Looker através do OAuth

O Looker usa o OAuth para permitir que as aplicações cliente OAuth se autentiquem na API Looker sem expor IDs de cliente e segredos do cliente ao navegador que está a executar a aplicação cliente OAuth.

As aplicações Web que usam o OAuth têm de cumprir os seguintes requisitos:

  • A autenticação através do OAuth só está disponível com a API Looker 4.0.
  • As aplicações cliente OAuth têm de ser registadas primeiro no Looker através da API antes de os utilizadores da aplicação poderem autenticar-se no Looker.
  • As aplicações cliente têm de usar HTTPS para todos os pedidos à API Looker. As aplicações cliente que queiram usar as SubtleCrypto APIs fornecidas pelo navegador têm de estar alojadas em HTTPS.

Compatibilidade com CORS da API Looker

A API Looker suporta a chamada no navegador e em várias origens através do protocolo de partilha de recursos de origem cruzada (CORS). O suporte de CORS do Looker tem os seguintes requisitos:

  • Apenas as origens listadas na lista de autorizações de domínios incorporados podem chamar a API através de CORS.
  • Só é possível usar tokens de acesso obtidos a partir do OAuth ou da chamada do ponto final da API /login para fazer chamadas à API Looker através de CORS.

    Não é possível chamar o ponto final da API /login através de pedidos CORS. As aplicações cliente que pretendam chamar a API Looker através de pedidos CORS têm de usar o processo de início de sessão OAuth descrito no artigo Realizar o início de sessão do utilizador através do OAuth ou obter um token do servidor da aplicação ou de chamadas API não CORS.

Vista geral da autenticação OAuth

Segue-se uma vista geral do processo de autenticação OAuth:

  1. Registe a aplicação cliente OAuth na API Looker.
  2. Adicione a origem da sua aplicação cliente OAuth à lista de autorizações de domínios incorporados para a chamada API de troca de código e quaisquer chamadas API CORS subsequentes.
  3. Redirecione o URL do navegador para o ponto final /auth no nome do anfitrião da IU do Looker (não no nome do anfitrião da API Looker) quando a aplicação cliente OAuth tenta autenticar um utilizador. Por exemplo, https://instance_name.looker.com.
  4. Se a autenticação do utilizador for bem-sucedida e este iniciar sessão no Looker, o Looker devolve imediatamente um redirecionamento OAuth à aplicação cliente OAuth. Se o utilizador ainda não tiver sessão iniciada no Looker no dispositivo e no navegador, é apresentado o ecrã de início de sessão do Looker e é-lhe pedido que inicie sessão na respetiva conta de utilizador do Looker através do protocolo de autenticação normal.
  5. Usando o código de autorização devolvido no redirecionamento do OAuth, a sua aplicação cliente OAuth deve fazer uma chamada ao ponto final /token no nome do anfitrião da API Looker, por exemplo, https://instance_name.looker.com:19999. O nome de anfitrião da API pode ser igual ou diferente do nome de anfitrião da IU do Looker. O ponto final /token existe apenas no anfitrião da API Looker e o ponto final /auth existe apenas no anfitrião da IU do Looker.
  6. Se o código de autorização transmitido ao ponto final /token for válido, o Looker devolve um access_token da API que está ativado para pedidos da API CORS a partir do domínio da aplicação cliente OAuth.

Registar uma aplicação cliente OAuth

Todas as aplicações cliente OAuth que tentem autenticar-se na API Looker através do OAuth têm de ser registadas primeiro na instância do Looker antes de o Looker autorizar o acesso. Para registar uma aplicação cliente OAuth:

  1. Abra o API Explorer na sua instância do Looker.
  2. No menu pendente de versões, escolha a versão 4.0 – estável da API.
  3. No método Auth, encontre o ponto final da API register_oauth_client_app(). Também pode pesquisar "app OAuth" no campo Pesquisar. Pode usar o register_oauth_client_app() para registar a sua aplicação cliente OAuth no Looker. Clique no botão Executar, introduza os parâmetros no API Explorer e clique novamente em Executar para registar a aplicação cliente OAuth ou use o ponto final da API register_oauth_client_app() de forma programática. Os parâmetros register_oauth_client_app() obrigatórios são:

    • client_guid: um ID globalmente exclusivo para a aplicação
    • redirect_uri: o URI onde a aplicação vai receber um redirecionamento OAuth que inclui um código de autorização
    • display_name: o nome da aplicação apresentado aos utilizadores da aplicação
    • description: uma descrição da aplicação apresentada aos utilizadores numa página de divulgação e confirmação quando um utilizador inicia sessão pela primeira vez a partir da aplicação

    Os valores nos parâmetros client_guid e redirect_uri têm de corresponder exatamente aos valores que a aplicação cliente OAuth vai fornecer, ou a autenticação será recusada.

Realizar o início de sessão do utilizador através do OAuth

  1. Navegue para o utilizador até ao ponto final /auth no anfitrião da IU. Por 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 tenta autenticar o utilizador através do sistema de autenticação para o qual a instância do Looker está configurada.

    • Se o utilizador já tiver sessão iniciada no Looker no navegador atual (o que significa que existe um estado de cookie de início de sessão ativo), não lhe é pedido que introduza as respetivas credenciais de início de sessão.
    • Se for a primeira vez que este utilizador inicia sessão através desta aplicação cliente OAuth, o Looker apresenta uma página de divulgação e confirmação para o utilizador confirmar e aceitar. É apresentado o texto do parâmetro description usado quando a aplicação foi registada. A descrição deve indicar o que a aplicação pretende fazer com a conta do Looker do utilizador. Quando o utilizador clica em aceitar, a página é redirecionada para a aplicação redirect_uri.
    • Se o utilizador já tiver sessão iniciada no Looker no navegador atual e já tiver confirmado a página de divulgação, o início de sessão do OAuth é instantâneo e não tem interrupções visuais.
  2. A API Looker devolve um redirecionamento OAuth à aplicação cliente OAuth. Guarde o código de autorização indicado no parâmetro URI. Segue-se um exemplo de um URI de redirecionamento do OAuth:

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

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

  3. Faça um pedido Web ao ponto final /token na API Looker, transmitindo o código de autorização e as informações da sua aplicação. Por 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 fornece à aplicação cliente OAuth um token de acesso da API access_token. A resposta também contém um refresh_token, que pode usar mais tarde para obter um novo access_token sem interação do utilizador. Um refresh_token tem uma duração de um mês. Armazene o refresh_token em segurança.

    Todos os tokens neste sistema podem ser revogados pelo administrador do Looker em qualquer altura.