# How to ガイド - OAuth 2.0認証コードのバリエーション

OAuth 2.0認証コードフローは、Workato が API 認証を行う際に、特定のユーザーの権限を借用するための方法です。これは、ユーザーが最初に接続を試みたときに、ブラウザのポップアップを通じてユーザーの同意を得ることによって実行されます。

# サンプルコネクター - Podio

{
  title: 'My Podio connector',

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

    authorization: {
      type: "oauth2",

      authorization_url: lambda do
        "https://percolate.com/auth/oauth2"
      end,

      token_url: lambda do
        "https://podio.com/oauth/token"
      end,

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

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

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

      refresh_on: [401, 403],

      refresh: lambda do |connection, refresh_token|
        response = post("https://podio.com/oauth/token").
                      payload(
                        grant_type: "refresh_token",
                        client_id: connection["client_id"],
                        client_secret: connection["client_secret"],
                        refresh_token: refresh_token
                      )
        [
          { # This hash is for your tokens
            access_token: response["access_token"],
            refresh_token: response["refresh_token"]
          }
        ]   
      end,
    }
  },

  test: lambda do |connection|
    get('/oauth/scope')
  end,

  #More connector code here
}

# ステップ1 - コネクション項目の定義

この部分では、コネクションの確立を試みるユーザーに向けて表示すべき項目を Workato に指示します。認証コードによる認証を利用する場合は、ユーザーが Podio で生成したクライアント ID とクライアントシークレットが必要となります。

必要な情報 説明
クライアント ID これは、この特定のカスタムコネクターが API に登録した「ユーザー名」です。これを得るには、対象アプリケーション内の検証済みアプリケーションとして Workato を登録する必要があるかもしれません。
クライアントシークレット これは、この特定のカスタムコネクターが API に登録した「パスワード」です。これを得るには、対象アプリケーション内の検証済みアプリケーションとして Workato を登録する必要があるかもしれません。クライアントシークレットは決してほかの人たちと共有しないでください。

この指示は fields キーの中で行われます。このキーはハッシュの配列を受け入れ、その配列内の各ハッシュが、それぞれ個別の入力項目に対応しています。

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

設定済みの Podio のコネクション項目

TIP

項目を定義する際は、少なくとも name キーを指定する必要があります。さらに optionalhintcontrol_type といった追加的な属性があれば、その項目の別の要素をカスタマイズできます。クライアントシークレットのような機密情報に対しては、必ず control_typepassword として使用してください。

Workato 内の入力項目を定義する方法について、詳しくはこちらを参照してください。

アカウントプロパティを利用して、組織の静的なクライアント ID とシークレットを保存する

組織全体に向けたコネクターを構築する場合、接続の際に各個人がクライアント ID やシークレットを入力するのは非効率的ということが多くあります。Workato では、まさにそのような目的のためにアカウントプロパティを利用できるようになっており、そうした認証情報を安全に保存することができます。

コネクションのコードから client_idclient_secret の項目を削除し、代わりに account_property メソッドを使用して、適切な値を指しているプロパティを参照することができます。

HubSpot の例

authorization_url: lambda do |connection|
  client_id = account_property('hubspot_webhook_client_id')
  "https://app.hubspot.com/oauth/authorize?client_id=#{client_id}&response_type=code&scope=crm.objects.companies.read crm.objects.contacts.read crm.objects.deals.read"
end,

acquire: lambda do |connection, auth_code, redirect_uri|
  client_id = account_property('hubspot_webhook_client_id')
  client_secret = account_property('hubspot_webhook_client_secret')
  response = post("https://api.hubapi.com/oauth/v1/token").
    payload(client_id: client_id,
      client_secret: client_secret,
      grant_type: 'authorization_code',
      code: auth_code,
      redirect_uri: redirect_uri).
    request_format_www_form_urlencoded
  [
    {
      access_token: response['access_token'],
      refresh_token: response['refresh_token']
    },
    nil,
    nil
  ]
end,

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

この部分では、入力項目から受け取った値をコネクションの確立にどう利用するかについて Workato に指示します。これは、authorization キーを通じて処理されます。このキー内では、まず認証の種類 (type) を定義します。この場合は、oauth2 を使用する必要があります。

      type: "oauth2",

# ステップ3 - クライアント ID、クライアントシークレット、認証 URL、およびトークン URL の定義

OAuth 2の認証コード付与のバリエーションを利用する場合、コネクターに次の4つの重要な属性を提供してください。

  • 認証 URL - ユーザーはブラウザのポップアップを通じてこの URL にリダイレクトされ、認証を提供します。
  • トークン URL - コネクターは認証コードを認証 URL から取得した後、この URL にリクエストを送信して、アクセストークンを受信します。
  • クライアント ID - このコネクションに割り当てられた、OAuth アプリの公開 ID。
  • クライアントシークレット - このコネクションに割り当てられた、OAuth アプリの秘密鍵。
    authorization_url: lambda do |connection|
      "https://podio.com/oauth/authorize"
    end,

    token_url: lambda do |connection|
      "https://podio.com/oauth/token"
    end,

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

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

authorization_url の lambda 関数を定義する際、クライアント ID、リダイレクト URI、および状態を明示的に渡す必要はありません。それは Workato が代わりに担当します。場合によっては、URL にスコープを追加する必要があるかもしれません。アプリケーションで、あらかじめリダイレクト URI を登録することが要求されている場合は、次の URL を利用してください: https://www.workato.com/oauth/callback

token_url の lambda 関数を定義する際、クライアント ID、クライアントシークレット、および grant_type を明示的に渡す必要はありません。それは Workato が代わりに担当します。token_url リクエストでは、RFC 標準に従い、ペイロードの本文に関連情報が含まれた POST リクエストが使用されます。

client_idclient_secret を定義する際は、fields の部分から収集しておいたエンドユーザーの入力を利用できます。Workato は、それらの入力をコーディングすることは推奨していません。

有効期間の短い認証コードを有効期間の長いアクセストークンに交換するとき、Workato は token_url エンドポイントからのレスポンスに、主に access_tokenrefresh_token という2つの値が含まれることを想定しています。以下にレスポンスのサンプルを示します。

{
  "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_tokenrefresh_token に関連付けられた値が保存されます。

# ステップ4 - 以降の HTTP リクエストに対するアクセストークンの適用

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

access_token は、単純に apply キーに対するパラメータとして access_token を渡し、参照することで取得できます。この引数 access_token は、token_url の lambda 関数の出力から自動的に割り当てられます。

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

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

# ステップ5 - トークンの更新動作の定義

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

WARNING

すべての API が更新トークンの資格情報を発行するわけではありません。この要件については、API を確認してください。

アクセストークンの有効期限が切れた場合に備え、更新トークンを用いてアクセストークンを更新するためにコネクターが取るべき動作を定義することができます。

    refresh_on: [401, 403],

    refresh: lambda do |connection, refresh_token|
      response = post("https://podio.com/oauth/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 (更新トークン) を表す引数にアクセスできます。この lambda 関数で想定される出力は配列であり、その最初のインデックスは新しい access_token (アクセストークン) と新しい refresh_token (存在する場合) を表すハッシュとなります。これらは、長期間続く接続の初期値を更新するために使用されます。

refresh の lambda についての詳細は、SDK リファレンス - 認証を参照してください。

# ステップ6 - API のベース URI の設定

この部分では、API のベース URL を Workato に指示します。このキーは任意ですが、これを利用すると、コネクターのほかの部分で HTTP リクエストを定義する際に相対パスのみを入力できるようになります。base_uri の設定方法については、こちらを参照してください。

    base_uri: lambda do |connection|
      'https://podio.com'
    end

TIP

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

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

# ステップ7 - コネクションのテスト

エンドユーザーから収集する必要のある項目と、それらの項目からの入力をどう利用するかを定義したので、次はこのコネクションをテストする手段が必要です。これは test キー内で扱われます。

    test: lambda do
      get('/oauth/scope')
    end,

このブロックではエンドポイントを指定する必要があります。このエンドポイントは、直前に受け取った新しい資格情報を使ってサンプルリクエストを送信するために利用されます。HTTP レスポンスとして200 OK を受け取った場合、接続は成功となります。上記の例では、エンドポイント /oauth/scopeGET リクエストを送信し、入力された API キーが有効であればレスポンスとして200 OK を受け取ることが期待されています。

# 認証コード付与のバリエーション

通常の標準認証フローから逸脱するケースでは、acquire ブロックを使用してください。このブロックにより、認証プロセス中に発生する HTTP コールを定義できます。たとえば、API によっては、基本認証での POST リクエストを用いて認証トークンを取得する必要がある場合があります。

# acquire キーの使用

以下のケースでは、token_url ブロックのデフォルトがヘッダー認証であるため、acquire キーを使用して基本認証で POST HTTP コールを送信しています。その後、その POST コールに対するレスポンスから access_tokenrefresh_token を取得できます。

    authorization: {
      type: "oauth2",

      authorization_url: lambda do |connection|
        params = {
          response_type: "code",
          client_id: connection["client_id"]
        }.to_param

        "https://login.mypurecloud.com/oauth/authorize?" + params
      end,

      acquire: lambda do |connection, auth_code|
        response = post("https://login.mypurecloud.com/oauth/token").
          payload(
            grant_type: "authorization_code",
            code: auth_code,
            redirect_uri: "https://www.workato.com/oauth/callback"
          ).
          user(connection["client_id"]).
          password(connection["client_secret"]).
          request_format_www_form_urlencoded

        # After defining the POST method, we now need to define the 
        # output of the acquire key in a fashion that we can recognise
          [
            {
              access_token: response["access_token"],
              refresh_token: response["refresh_token"],
            },
            nil,
            # Optional. Will be merged into connection hash
            { instance_id: nil } 
          ]
        end,

        apply: lambda do |connection, access_token|
          headers("Authorization": "Bearer #{connection["access_token"]}")
        end
      }
    },

.user.password は、POST リクエストヘッダーに BASE-64 文字列エンコーディングで Authorization: BASIC および <user>:<password> を付加する処理と同等のメソッドです。リクエストは request_format_www_form_urlencoded で送信する必要があることに注意してください。

そのリクエストを受信すると、API は以下のような JSON レスポンスを返します。

{
  "access_token": 12345,
  "refresh_token": 12345,
  "settings": "no"
}

OAuth 2.0認証メソッドの acquire キーを使用する場合に想定される出力は、ハッシュの配列であることに注意してください。その配列の各インデックスには、次のような値を順番に含めます。

  • トークン - これは access_tokenrefresh_token の正確なキーを含むハッシュでなければなりません。更新トークンは省略可能です。
  • 所有者 ID - これは、上書きの検出に使用するオプションの値です (使用しない場合は nil を代入してください)。
  • その他の値 - ここでオプションのハッシュを提供して、元のコネクションハッシュに取り込むことができます。

以上は次のコネクターコードに対応します。

  [
    {
      access_token: response["access_token"],
      refresh_token: response["refresh_token"],
    },
    nil,
    # Optional. Will be merged into connection hash
    { instance_id: nil } 
  ]

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

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


Last updated: 2023/8/31 1:07:14