VBAでOAuth認証APIを安定接続:Bearerトークンを用いたMSXML2.XMLHTTPの実装

Tech

本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

VBAでOAuth認証APIを安定接続:Bearerトークンを用いたMSXML2.XMLHTTPの実装

【背景と目的】

OAuth 2.0が必要なモダンAPI連携において、参照設定なしで安定稼働させるためのBearerトークン認証ロジックを確立します。遅延バインディングとタイムアウト設定を駆使し、ネットワーク遅延や認証エラーで処理が停止する実務上の課題を解決します。

【処理フロー図】

MSXML2.ServerXMLHTTPを使用し、Bearer認証ヘッダーを付与してAPIを呼び出し、レスポンスを処理するフロー。

graph TD
    A["開始: 環境設定と変数宣言"] --> B{"アクセストークン取得済みか?"};
    B -- はい --> C["ServerXMLHTTPオブジェクト生成"];
    C --> D["タイムアウト設定とURL/メソッド指定"];
    D --> E["認証ヘッダー 'Authorization: Bearer' を設定"];
    E --> F["APIコール実行 objHttp.Send"];
    F --> G{"HTTPステータスコード判定"};
    G -- 200/202 --> H["成功: レスポンスを処理し結果を配列に格納"];
    G -- 4xx/5xx --> I["失敗: エラーログ出力とオブジェクトクリーンアップ"];
    H --> J["終了"];
    I --> J;

【実装:VBAコード】

1. Bearerトークン認証によるAPIコール関数

この関数は、APIエンドポイントと有効なアクセストークンを受け取り、JSONレスポンス文字列を返します。ネットワークの安定性を高めるため、遅延バインディングでMSXML2.ServerXMLHTTPを使用し、タイムアウト設定を明示します。

Option Explicit

' 環境に依存しない遅延バインディングを使用
Private Const HTTP_OBJECT_NAME As String = "MSXML2.ServerXMLHTTP"

' ----------------------------------------------------------------------
' 機能:Bearer認証ヘッダーを付与してREST APIを呼び出す
' 引数:strURL        - APIエンドポイントURL
'       strAccessToken - Bearerトークン(OAuth 2.0で取得済み)
' 戻り値:APIからの応答テキスト (JSON形式が多い)
' ----------------------------------------------------------------------
Public Function CallAuthenticatedApi(ByVal strURL As String, ByVal strAccessToken As String) As String

    Dim objHttp As Object
    Dim strResponse As String
    Dim lngStatus As Long

    ' 高速化のための初期設定(Excelの場合、Accessでは不要)
    If TypeName(Application) = "Application" Then
        Application.ScreenUpdating = False
        Application.EnableEvents = False
    End If

    On Error GoTo ErrorHandler

    ' MSXML2.ServerXMLHTTPオブジェクトの遅延バインディングによる生成
    ' ※HTTPS通信の安定性やタイムアウト設定機能があるため推奨
    Set objHttp = CreateObject(HTTP_OBJECT_NAME)

    ' 安定性のためのタイムアウト設定(ミリ秒単位)
    ' Resolve, Connect, Send, Receive の順。ここではすべて30秒に設定
    objHttp.SetTimeouts 30000, 30000, 30000, 30000 

    ' APIコールの準備 (GETメソッドを使用する前提)
    objHttp.Open "GET", strURL, False ' False: 同期モード

    ' 必須ヘッダーの設定 ------------------------------------------------

    ' 1. Bearer認証ヘッダーの付与(OAuthの核心)
    objHttp.setRequestHeader "Authorization", "Bearer " & strAccessToken

    ' 2. 受信するデータの形式を指定(通常はJSON)
    objHttp.setRequestHeader "Accept", "application/json"

    ' 3. 送信するデータの形式を指定(GETでは通常不要だがPOST/PUTでは必須)
    ' objHttp.setRequestHeader "Content-Type", "application/json"

    ' APIの実行
    objHttp.Send

    ' レスポンスの確認
    lngStatus = objHttp.Status

    If lngStatus >= 200 And lngStatus < 300 Then
        ' 成功 (200 OK, 201 Created, 202 Accepted など)
        strResponse = objHttp.responseText
    Else
        ' 失敗 (4xx クライアントエラー, 5xx サーバーエラー)
        Debug.Print "API Error: Status " & lngStatus
        Debug.Print "Response: " & objHttp.responseText
        strResponse = "" ' エラー時は空文字を返す
    End If

CleanUp:
    ' オブジェクトの解放
    Set objHttp = Nothing

    ' 高速化設定の復元
    If TypeName(Application) = "Application" Then
        Application.ScreenUpdating = True
        Application.EnableEvents = True
    End If

    CallAuthenticatedApi = strResponse
    Exit Function

ErrorHandler:
    ' 予期せぬ実行時エラーが発生した場合の処理
    Debug.Print "Runtime Error in API Call: " & Err.Description
    strResponse = ""
    Resume CleanUp

End Function

' ----------------------------------------------------------------------
' 使用例:取得したJSONデータを処理する(※JSONパースは別途対応が必要)
' ----------------------------------------------------------------------
Sub Test_ApiIntegration()

    Dim sUrl As String
    Dim sToken As String
    Dim sJsonResult As String

    ' プレースホルダー: 実際のURLとトークンに置き換えること
    sUrl = "https://api.example.com/v1/resource"
    sToken = "ya29.a0AR..." ' 認証サーバーから取得した有効なアクセストークン

    ' APIコール実行
    sJsonResult = CallAuthenticatedApi(sUrl, sToken)

    If sJsonResult <> "" Then
        MsgBox "APIコール成功。データを受信しました(文字数: " & Len(sJsonResult) & ")", vbInformation
        ' ここで sJsonResult (JSON文字列) を必要な形式にパースする処理が続く

        ' 例: 簡易的なJSON構造のチェック
        If InStr(sJsonResult, """id"":") > 0 Then
            Debug.Print "JSON Response Snippet: " & Left(sJsonResult, 200)
        End If

    Else
        MsgBox "APIコール失敗、または認証エラーが発生しました。", vbCritical
    End If

End Sub

【技術解説】

1. MSXML2.ServerXMLHTTPの選択

通常の MSXML2.XMLHTTP はIEコンポーネントに依存しますが、MSXML2.ServerXMLHTTP はサーバーサイドでの利用を想定しており、以下の利点があります。

  • HTTPS接続の安定性: SSL/TLS認証処理が安定しており、モダンAPIとの連携に適しています。

  • タイムアウト設定: SetTimeouts メソッドを利用できるため、ネットワークの不安定さやサーバーの応答遅延によってVBAプロセス全体がフリーズするのを防ぐことができます。これは実務における安定運用に不可欠です。

2. Bearer認証ヘッダーの構造

OAuth 2.0で最も一般的に使用されるトークン伝達方式がBearerトークンです。APIリクエストでは、HTTPヘッダーに以下の形式でトークンを付与する必要があります。

Authorization: Bearer [ここにトークンを記述]

VBAコードではこれを objHttp.setRequestHeader "Authorization", "Bearer " & strAccessToken として実装しています。

3. 遅延バインディングの採用

CreateObject("MSXML2.ServerXMLHTTP") を使用することで、プロジェクトの「参照設定」を行う必要がなくなります。これにより、VBA環境(Excel/Accessのバージョンやビット数)に依存せず、コードの移植性と互換性が大幅に向上します。

【注意点と運用】

1. 落とし穴:トークンの有効期限と更新

OAuthトークンには有効期限(Expiration Time)があります。

  • 課題: トークンが期限切れの状態でAPIを叩くと、通常401 Unauthorizedエラーが返されます。

  • 回避策: トークンの発行時刻と有効期限をデータベースや設定ファイルに保存し、APIコール前に有効期限をチェックするロジックを組み込みます。期限切れの場合は、リフレッシュトークン(取得可能な場合)を使って新しいアクセストークンを再取得する処理を自動実行する必要があります。

2. 環境依存性(ServerXMLHTTPのバージョン)

上記コードでは、Windows標準で提供されている MSXML2.ServerXMLHTTP を使用していますが、ごく古い環境ではバージョンの指定が必要になる場合があります(例: MSXML2.ServerXMLHTTP.6.0)。MSXML2.ServerXMLHTTP でエラーが出る場合は、代わりに MSXML2.ServerXMLHTTP.6.0MSXML2.ServerXMLHTTP.3.0 を試す必要があります。

3. 送信データ(POST/PUT時)のエンコード

POSTやPUTでボディデータを送信する場合、JSON文字列をUTF-8で正しくエンコードする必要があります。MSXML2は通常、ボディのエンコードを自動で行いますが、文字化けを防ぐため、常に Content-Type: application/json; charset=utf-8 をヘッダーに追加することを推奨します。

【まとめ】

OAuth認証APIをVBAで安定運用するためのコツは以下の3点に集約されます。

  1. ServerXMLHTTPとタイムアウト: 標準の XMLHTTP ではなく ServerXMLHTTP を使用し、SetTimeouts でネットワーク遅延によるプロセスフリーズを回避します。

  2. Bearer認証の厳密な適用: Authorization ヘッダーは必ず Bearer (Bearerの後にスペース) を付与した正確な形式で設定します。

  3. トークン管理の外部化: アクセストークンとリフレッシュトークン(あれば)はVBAコード内に直書きせず、有効期限管理を含めてAccessテーブルや設定ファイルで一元管理し、APIコール前に検証する運用フローを構築します。

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

タイトルとURLをコピーしました