OAuth を使用した Looker API 認証

Looker では、OAuth を使用して、OAuth クライアント アプリケーションが実行されているブラウザにクライアント ID とクライアント シークレットを公開することなく、OAuth クライアント アプリケーションを Looker API に対して認証できるようにします。

OAuth を使用するウェブ アプリケーションは、次の要件を満たす必要があります。

  • OAuth による認証は、Looker API 4.0 でのみ使用できます。
  • アプリケーションのユーザーが Looker への認証を行う前に、OAuth クライアント アプリケーションを API を使用して Looker に登録する必要があります。
  • クライアント アプリケーションは、Looker API へのすべてのリクエストに HTTPS を使用する必要があります。ブラウザが提供する SubtleCrypto API を使用するクライアント アプリケーションは、HTTPS でホストされている必要があります。

Looker API CORS のサポート

Looker API は、クロスオリジン リソース シェアリング(CORS)プロトコルを使用して、ブラウザ内およびオリジン間で呼び出すことができます。Looker の CORS サポートには、次の要件があります。

  • 埋め込みドメインの許可リストに記載されているオリジンのみが、CORS を使用して API を呼び出すことができます。

  • CORS を使用して Looker API を呼び出すには、OAuth または /login API エンドポイントの呼び出しから取得したアクセス トークンのみを使用できます。

OAuth 認証の概要

OAuth 認証プロセスの概要は次のとおりです。

  1. Looker インスタンスに OAuth クライアント アプリケーションを登録します。
  2. OAuth クライアント アプリケーションの送信元を、コード交換 API 呼び出しと後続の CORS API 呼び出しのために埋め込みドメインの許可リストに追加します。

  3. OAuth クライアント アプリケーションがユーザーを認証しようとしたときに、Looker UI ホスト名(Looker API ホスト名ではない)のブラウザ エンドポイントを /auth エンドポイントにリダイレクトします。 例: https://instance_name.looker.com

  4. ユーザーが正常に認証され、Looker にログインすると、Looker はすぐに OAuth クライアント アプリケーションへの OAuth リダイレクトを返します。ユーザーがデバイスとブラウザで Looker にまだログインしていない場合は、Looker のログイン画面が表示され、ユーザーは通常の認証プロトコルを使用して Looker ユーザー アカウントにログインするよう求められます。

  5. OAuth リダイレクトで返された認証コードを使用して、OAuth クライアント アプリケーションが次に Looker API ホスト名(https://instance_name.looker.com:19999 など)の /token エンドポイントを呼び出す必要があります。API ホスト名は、Looker UI ホスト名と同じ場合もあれば、異なる場合もあります。/token エンドポイントは Looker API ホストにのみ存在し、/auth エンドポイントは Looker UI ホストにのみ存在します。

  6. /token エンドポイントに渡された認証コードが有効な場合、Looker は OAuth クライアント アプリケーションのドメインからの CORS API リクエストに対して有効な API access_token を返します。

OAuth クライアント アプリケーションの登録

OAuth を使用して Looker API への認証を試みるすべての OAuth クライアント アプリケーションは、Looker がアクセスを承認する前に、Looker インスタンスにまず登録する必要があります。

Looker 管理者は、[OAuth クライアントの管理] ページ([管理] > [認証] > [OAuth クライアントの管理])の Looker [管理パネル] で、カスタム OAuth クライアント アプリケーションを直接登録して管理できます。このインターフェースを使用すると、管理者は次のタスクを実行できます。

  • 複数の環境とポートをサポートするように、アプリケーションに 1 つ以上の承認済みリダイレクト URI を構成します。
  • 特定の Looker ユーザー グループのメンバーに認可アクセスを制限する(グループ ID に制限)。
  • 登録済みのカスタム アプリケーションを表示、編集、有効化、無効化、削除する。

[管理] パネルでカスタム クライアントを登録する手順ガイドについては、管理設定 - OAuth クライアントの管理のドキュメント ページをご覧ください。

API を使用したプログラムによる登録

また、管理者は、OAuth アプリのエンドポイントを登録を直接呼び出すか、Looker API Explorer で実行することで、OAuth クライアント アプリケーションをプログラムで登録できます。パラメータには次のものがあります。

  • client_guid: アプリケーションの一意の文字列 ID(com.looker. で始めることはできません)。
  • redirect_uris: アプリケーションが OAuth リダイレクトと認証コードを受け取る承認済みコールバック URI の配列。
  • display_name: ユーザーに表示されるアプリケーションの名前。
  • description: OAuth クライアント アプリケーションの説明。
  • group_id(省略可): アクセスを制限する Looker グループの数値 ID。

OAuth を使用したユーザー ログインの実行

  1. UI ホストの /auth エンドポイントにユーザーを誘導します。次に例を示します。

    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
    }
    

    Looker は、Looker インスタンスが構成されている認証システムを使用してユーザーの認証を試みます。

    • 現在のブラウザで Looker にすでにログインしている場合(つまり、ライブログイン Cookie の状態がある場合)、ユーザーはログイン認証情報の入力を求められません。
    • このユーザーがこの OAuth クライアント アプリケーションを使用して初めてログインする場合、Looker では開示ページと確認ページが表示され、ユーザーの確認と同意が行われます。アプリケーションの登録時に使用された description パラメータのテキストが表示されます。説明には、アプリケーションがユーザーの Looker アカウントで何を行うかを記載する必要があります。ユーザーが [accept] をクリックすると、ページはアプリケーション redirect_uri にリダイレクトされます。
    • ユーザーが現在のブラウザで Looker にログイン済みであり、すでに開示ページに確認応答している場合、OAuth ログインは視覚的な中断を生じることなく瞬時に完了します。
  2. Looker API は、OAuth クライアント アプリケーションへの OAuth リダイレクトを返します。URI パラメータに表示されている認証コードを保存します。OAuth リダイレクト URI の例を次に示します。

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

    認可コードは、URI の &code= の後に表示されます。この例では、認証コードは asdfasdfassdf です。

  3. Looker API の /token エンドポイントにウェブ リクエストを送信し、認証コードとアプリケーション情報を渡します。次に例を示します。

    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
    }
    

    応答の受信に成功すると、OAuth クライアント アプリケーションに API access_token が返されます。レスポンスには refresh_token も含まれます。これは、後でユーザーの操作なしで新しい access_token を取得するために使用できます。refresh_token の有効期間は 1 か月です。refresh_token を安全に保存します。

    このシステムのすべてのトークンは、Looker 管理者がいつでも取り消すことができます。