ハウツーガイド - Proof Key for Code Exchange(PKCE)を使用したOAuth 2.0認可コードバリアント

このページは機械翻訳により提供されています。翻訳内容と英語版に相違がある場合は、英語版が優先されます。

OAuth 2.0認可コードフローは、WorkatoがAPIへの認証時に特定のユーザーになりすますための方法です。 これは、ユーザーが初めて接続を試みるときに、ブラウザーポップアップを通じてユーザーの同意を得ることで行われます。 PKCEを使用するこのバリアントでは、authorization URLでchallengeが提示され、最後のトークン交換リクエストでverifierが提示される追加の検証ステップがあります。

サンプルコネクター - Dropbox

ruby
{
  title: "Dropbox pkce",

  connection: {
    fields: [
      { name: 'client_id' },
      { name: 'client_secret' }
    ],
    authorization: {
      type: "oauth2",

      client_id: lambda do |connection|
        connection['client_id']
      end,

      client_secret: lambda do |connection|
        connection['client_secret']
      end,

      pkce: lambda do |verifier, challenge|
        {
          verifier: verifier,
          challenge: challenge,
          challenge_method: "S256"
        }
      end,

      authorization_url: lambda do |connection|
        "https://www.dropbox.com/oauth2/authorize?client_id=#{connection['client_id']}&response_type=code"
      end,

      token_url: lambda do |_connection|
        "https://api.dropbox.com/oauth2/token"
      end,

      apply: lambda do |_connection, access_token|
        headers('Authorization': "Bearer #{access_token}")
      end
    },
  },

  test: lambda do |_connection|
    post("https://api.dropboxapi.com/2/check/app", {})
  end,

  # その他のコネクターコードをここに記述
}

Step 1 - コネクションフィールドの定義

このコンポーネントは、コネクションを確立しようとしているユーザーに表示するフィールドをWorkatoに指示します。 PKCEを使用した認可コードグラントの場合、ユーザーがDropboxの開発者コンソールで生成したClient IDとClient Secretが必要です。

これは、ハッシュの配列を受け入れるfieldsキーで実行されます。 この配列内の各ハッシュは、個別の入力フィールドに対応します。

ruby
    fields: [
      {
        name: 'client_id',
        optional: false
      },
      {
        name: 'client_secret',
        optional: false,
        control_type: 'password'
      }
    ],

TIP

フィールドを定義するときは、少なくともnameキーを指定する必要があります。 optionalhintcontrol_typeなどの追加属性を使用すると、これらのフィールドの他の側面をカスタマイズできます。 Client Secretなどの機密情報には、control_typeとしてpasswordを使用してください。

Workatoで入力フィールドを定義する方法の詳細を確認してください。

ステップ2 - 認可タイプの定義

このコンポーネントは、コネクションを確立するために、入力フィールドから受け取った値をどのように処理するかをWorkatoに指示します。 これはauthorizationキーで処理されます。 このキーでは、まず認可のtypeを定義します。 この場合、Authorization Code Grantフローと同様に、oauth2を使用する必要があります。

ruby
      type: "oauth2",

Step 3 - Client ID、Client Secret、およびPKCEパラメーターの定義

これらのコンポーネントにより、SDKフレームワークは、後でclient ID、client secret、およびPKCEパラメーターに何を使用するかを把握できます。

ruby
      client_id: lambda do |connection|
        connection['client_id']
      end,

      client_secret: lambda do |connection|
        connection['client_secret']
      end,

      pkce: lambda do |verifier, challenge|
        {
          verifier: verifier,
          challenge: challenge,
          challenge_method: "S256"
        }
      end,

この例では、client IDとsecretに対するユーザーの入力を、それぞれ関連するclient_idおよびclient_secretラムダに単純にマッピングします。 これは、前に定義したfields内のユーザー入力を表すハッシュであるconnection引数を使用して行います。

次に、pkceラムダも定義する必要があります。これは、これがPKCEを使用したAuthorization Code Grant Flowであることを示す重要なマーカーです。 このラムダ内では、verifierchallengeに対応する2つの引数を受け取ります。 例に示すように、これらの両方の引数をそのまま使用し、pkceラムダの出力として渡すことができます。

Step 4 - authorization urlおよびtoken urlの定義

OAuth 2のPKCEバリアントでは、通常のauth code grantフローと同様に、authorization urlとtoken urlの2つを指定します。

  • 認可URL - ユーザーが認可を行うために、ブラウザーポップアップ経由でリダイレクトされる場所。
  • トークンURL - このコネクターが認可URLから認可コードを受け取った後、アクセストークンを受け取るためにリクエストを送信する場所。
ruby
  authorization_url: lambda do |connection|
    "https://www.dropbox.com/oauth2/authorize"
  end,

  token_url: lambda do |connection|
    "https://api.dropbox.com/oauth2/token"
  end,

authorization_urlラムダ関数を定義すると、Workatoは次のパラメーターを自動的に渡します。

  • client ID
  • redirect URI
  • code challenge
  • state

場合によっては、必要に応じてURLにscopeを追加する必要があります。 アプリケーションでredirect URIの事前登録が必要な場合は、次のURLを使用します: https://www.workato.com/oauth/callback

token_urlラムダ関数を定義すると、Workatoは次のパラメーターを自動的に渡します。

  • client ID
  • client secret
  • code verifier
  • grant_type

token_urlリクエストでは、RFC標準に従い、関連情報をペイロード本文に含めたPOSTリクエストを使用します。 Workatoが有効期間の短い認可コードを有効期間の長いアクセストークンと交換する場合、token_urlエンドポイントからのレスポンスに2つの主な値、access_tokenrefresh_tokenが含まれていることを想定しています。 レスポンスのサンプルを次に示します。

json
{
  "access_token": "my-authentication-token",
  "token_type": "bearer",
  "expires_in": "seconds-until-expiration",
  "refresh_token": "my-refresh-token",
  "error": "optional-error-message",
  "ref":
  {
    "type": "user",
    "id": USER_ID
  }
}

認証では、access_tokenおよびrefresh_tokenに関連付けられた値が保存されます。

Step 5 - 後続のHTTPリクエストへのaccess tokenの適用

applyキーでは、取得したアクセストークンをヘッダー入力として適用します。

applyキーにパラメーターとしてaccess_tokenを渡すだけで、access_tokenを取得できます。 この引数access_tokenは、token_urlラムダ関数の出力から自動的に割り当てられます。

ruby
    apply: lambda do |connection, access_token|
      headers("Authorization": "OAuth2 #{access_token}")
    end,

コネクションオブジェクトで使用可能なパラメーターとキーの詳細については、SDKリファレンス - コネクションを参照してください。

Step 6 - トークン更新動作の定義

ほとんどの場合、OAuth 2.0認証には、有効期間の短いアクセストークンと有効期間の長いリフレッシュトークンの両方があります。 リフレッシュトークンには有効期限がない場合もあります。

WARNING

すべてのAPIがrefresh token認証情報を発行するわけではないことに注意してください。 この要件については、APIに確認してください。

アクセストークンの有効期限が切れた場合に、リフレッシュトークンを使用してアクセストークンを更新するためにコネクターが実行する動作を定義できます。

ruby
    refresh_on: [401, 403],

    refresh: lambda do |connection, refresh_token|
      response = post("https://api.dropbox.com/oauth2/token").
                    payload(
                      grant_type: "refresh_token",
                      client_id: connection["client_id"],
                      client_secret: connection["client_secret"],
                      refresh_token: refresh_token,
                      redirect_uri: 'https://www.workato.com/oauth/callback'
                    )
      [
        {
          access_token: response["access_token"],
          refresh_token: response["refresh_token"]
        }
      ]
    end,

アクセストークンを更新するには、authorizationキーでrefresh_onrefreshの2つのキーを使用する必要があります。 refresh_onは、HTTPレスポンスコードまたは正規表現文字列を含めることができる配列を受け入れます。 コネクター内のHTTPリクエストがいずれかのHTTPレスポンスコードを受け取った場合、またはペイロードの本文が正規表現文字列に一致した場合、refreshキー内のコードが実行され、新しいアクセストークンの取得を試みます。

refreshキーでは、最初のトークンリクエストから受け取ったrefresh_tokenを表す引数にアクセスできます。 このラムダ関数の想定される出力は配列であり、最初のインデックスは新しいaccess_tokenと、該当する場合は新しいrefresh_tokenを示すハッシュです。 これらは、長期間持続するコネクションの初期値を更新するために使用されます。

refreshラムダの詳細については、SDKリファレンス - authorizationを参照してください。

Step 7 - APIのbase URIの設定

このコンポーネントは、APIのベースURLをWorkatoに指示します。 このキーは任意ですが、HTTPリクエストを定義する際に、コネクターの残りの部分で相対パスのみを指定できるようになります。 base URIを設定する方法を確認してください。

ruby
    base_uri: lambda do |connection|
      'https://api.dropboxapi.com'
    end

TIP

このラムダ関数はconnection引数にもアクセスできます。 これは、ユーザーのインスタンスに基づいてAPIのベースURIが変わる可能性がある場合に特に便利です。 connection引数には次の形式でアクセスできます。

ruby
    base_uri: lambda do |connection|
      "https://#{connection['domain'].com/api}"
    end

Step 8 - コネクションのテスト

エンドユーザーから収集する必要があるフィールドと、それらのフィールドからの入力をどう処理するかを定義したので、次にこのコネクションをテストする方法が必要です。 これはtestキーで処理されます。

ruby
    test: lambda do
      post("https://api.dropboxapi.com/2/check/app", {})
    end,

このブロックでは、受け取ったばかりの新しい認証情報を使用してサンプルリクエストを送信できるエンドポイントを指定する必要があります。 200 OK HTTPレスポンスを受信すると、コネクションをSuccessfulとして表示します。 上記の例では、受け取ったばかりのaccess tokenが有効な場合に200応答が返ることを想定して、/2/check/appエンドポイントにPOSTリクエストを送信しています。

Auth code grant PKCEバリエーション

場合によっては、トークンリクエストを完了するためにacquireラムダを使用する必要があります。 ここでは、acquireラムダを使用する点を除き、同じDropboxコネクションの例を示します。

ruby
  connection: {
    fields: [
      { name: 'client_id' },
      { name: 'client_secret' }
    ],
    authorization: {
      type: "oauth2",

      client_id: lambda do |connection|
        connection['client_id']
      end,

      client_secret: lambda do |connection|
        connection['client_secret']
      end,

      pkce: lambda do |verifier, challenge|
        {
          verifier: verifier,
          challenge: challenge,
          challenge_method: "S256"
        }
      end,

      authorization_url: lambda do |connection|
        "https://www.dropbox.com/oauth2/authorize?client_id=#{connection['client_id']}&response_type=code"
      end,

      acquire: lambda do |connection, auth_code, redirect_uri, verifier|
        response = post("https://api.dropbox.com/oauth2/token",
          grant_type: "authorization_code",
          code: auth_code,
          redirect_uri: redirect_uri,
          client_secret: connection["client_secret"],
          code_verifier: verifier,
          client_id: connection["client_id"]
        ).request_format_www_form_urlencoded

        [
          {
            access_token: response["access_token"],
            refresh_token: response["refresh_token"],
            refresh_token_expires_in: response["expires_in"] # Expiration time of the refresh token from now in seconds
          },
          nil,
          { instance_id: nil }
        ]
      end,

      apply: lambda do |_connection, access_token|
        headers('Authorization': "Bearer #{access_token}")
      end
    },
  },

acquireラムダで追加の引数verifierを受け取ることに注意してください。これは、pkceラムダの出力として渡したものと同じverifierに対応します。

コネクションSDKリファレンス

connectionキー内で使用可能なキーとそのパラメーターに慣れるには、SDKリファレンスを確認してください。

Last updated: