導入・活用の解説

VBAからSalesforceのAPIを呼び出す現行の認証手順

SalesforceへログインしてレコードをまとめてExcelへ持ってくるVBAは、いまも現場で使われています。ただし当時の記事のようにユーザー名とパスワードをSOAP APIのlogin()へそのまま渡す書き方は、APIバージョン65.0以降では使えず、Summer '27ですべてのバージョンで廃止されます。認証をどう組み立て直すか、VBAでどこまでできるかを説明します。

2023.02.16

なぜいまの書き方を直すのか

当時の記事では、SOAP APIのlogin()呼び出しへユーザー名とパスワードをそのまま埋め込み、セッションIDを取得する作りでした。動くこと自体は否定しませんが、認証情報をコードへ直接書く形は、いまのSalesforceが強く避けている書き方です。SOAP APIのlogin()は、APIバージョン65.0以降で使えず、Summer '27ですべてのバージョンで廃止されます。同じようにユーザー名とパスワードを渡すOAuth 2.0のユーザー名パスワードフローも、Summer '23以降に作成された組織では既定でブロックされています。この記事では、Connected Appを使った現行の認証の組み立て方と、VBAだけで完結しない部分を整理します。

ユーザー名パスワードフローがブロックされている理由

Summer '23以降に作成された組織では、OAuth 2.0のユーザー名パスワードフローが既定でブロックされます。有効化すること自体は可能ですが、Salesforceはこのフローを推奨していません。代わりに、OpenID Connectの動的クライアント登録、クライアント認証情報フロー、PKCE拡張つきのWebサーバーフローなどへ切り替えるよう案内されています。ExcelのVBAのように対話的なログイン画面を持たない自動処理では、サーバー間連携向けのJWTベアラーフローが現実的な選択肢です。

変更前変更後
SOAP APIのlogin()にユーザー名とパスワードを直接渡すConnected AppでJWTベアラーフローを設定し、署名済みJWTと引き換えにアクセストークンを得る
セッションIDをそのままAPI呼び出しに使うアクセストークンとinstance_urlを使ってREST APIを呼ぶ

JWTベアラーフローの準備

OAuth 2.0のJWTベアラーフローは、対話的なログインなしにアクセストークンを得るための仕組みです。クライアントが署名済みのJWTをSalesforceのトークンエンドポイントへ送り、Salesforceが署名を検証してからアクセストークンを発行します。準備するものは次の3つです。

  1. X509証明書を用意する

    4KB以下のX509証明書を作成します。大きい場合はDER形式へ圧縮します。

  2. Connected Appに証明書を登録する

    デジタル署名を使うオプションを有効にし、証明書をアップロードします。登録するとclient_idとclient_secretが発行されます。

  3. RS256で署名したJWTを用意する

    ヘッダーに{"alg":"RS256"}、クレームにiss(client_id)・sub(ログインするユーザー名)・aud(ログインURL)・exp(有効期限)を含め、証明書の秘密鍵で署名します。

⚠️ このフローはリフレッシュトークンを発行しません。アクセストークンの有効期限が切れたら、署名済みJWTを使ってもう一度トークンエンドポイントを呼び直します。

VBAで実装するときの制約

Excelのリボンで開発タブが選ばれ、左端にVisual Basicのボタンが並んでいる
まずExcelの開発タブを開きます。左端のVisual Basicから、コードを書くエディタへ進みます。
VBAの参照設定ダイアログ。Microsoft XML v3.0にチェックが入っている
参照設定のダイアログです。MSXML2.XMLHTTPを使うので、Microsoft XMLにチェックが入っているかを見てください。

トークンエンドポイントへのPOSTと、そのあとのREST API呼び出し自体は、VBAのHTTPオブジェクトでそのまま書けます。ただし、JWTのRS256署名はVBAの標準機能だけでは作れません。署名には秘密鍵を使ったRSA暗号処理が必要で、VBA単体にはその機能がないためです。実務では、署名済みJWTを外部のツールやサービスで作ってExcel側へ渡す、または証明書を扱えるライブラリをVBAから呼び出す構成になります。この記事では、その手前のトークン取得とAPI呼び出しの形を示します。

Dim http As Object
Set http = CreateObject("MSXML2.XMLHTTP")
Dim tokenUrl As String
tokenUrl = "https://xxxx.my.salesforce.com/services/oauth2/token"
Dim body As String
body = "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=" & signedJwt
http.Open "POST", tokenUrl, False
http.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
http.send body
If http.Status <> 200 Then
    MsgBox "token status:" & http.Status
    Exit Sub
End If
Dim tokenJson As String
tokenJson = http.responseText

OAuth 2.0のJWTベアラーフローでアクセストークンを取得するVBAです。signedJwtには、あらかじめRS256で署名したJWTを渡します。

tokenUrlのxxxx部分は、実際にはご自身の組織のMy Domain名に置き換えます。レスポンスのJSONにはaccess_tokenとinstance_urlが含まれます。VBAには標準のJSONパーサーがないため、文字列処理か外部ライブラリで値を取り出します。

レコードを取得するVBA

アクセストークンとinstance_urlが手に入れば、あとはREST APIへのGETリクエストです。当時の記事ではAPIバージョン40.0を使っていました。Summer '26時点のAPIバージョンは67.0です。

Dim restTargetURL As String
restTargetURL = instanceUrl & "/services/data/v67.0/query/?q=" & _
    "SELECT+Id+FROM+Account"
Dim httpObj As Object
Set httpObj = CreateObject("MSXML2.XMLHTTP")
httpObj.Open "GET", restTargetURL, False
httpObj.setRequestHeader "Authorization", "Bearer " & accessToken
httpObj.setRequestHeader "Accept", "application/json"
httpObj.send
MsgBox httpObj.responseText

取引先のIdをREST APIで取得するVBAです。accessTokenとinstanceUrlは、トークンエンドポイントのレスポンスから取り出した値です。

当時の記事のコードにあった、レスポンスから正規表現でサーバーのドメインを取り出す処理は不要になります。instance_urlがそのままクエリのベースURLです。

動作確認

呼び出し確認すること
トークンエンドポイントへのPOSTステータスが200で、レスポンスJSONにaccess_tokenとinstance_urlが含まれること
クエリのGETステータスが200で、レスポンスJSONのtotalSizeとrecordsに取引先のIdが並ぶこと

ここで間違えやすい

間違い何が起きるか
ユーザー名とパスワードをそのままログイン処理に埋め込むSOAP APIのlogin()はAPIバージョン65.0以降で使えません。OAuthのユーザー名パスワードフローも、Summer '23以降に作成された組織では既定でブロックされ通りません
アクセストークンの有効期限切れに気づかないREST API呼び出しがINVALID_SESSION_IDで失敗します。JWTベアラーフローはリフレッシュトークンを発行しないため、再度トークンエンドポイントを呼び直します
APIバージョンを古いまま(40.0など)で書く動くことはありますが、新しい機能やフィールドの挙動が反映されません。現行バージョンへ上げてください

確認した環境

  • 2026年9月/Salesforce Summer '26(APIバージョン67.0)時点の公式ドキュメントで、OAuthのフロー一覧とREST APIのクエリ形式を確認しています
  • JWTの署名部分は、ご自身の環境に合わせて実装してください

まとめ

  • ユーザー名とパスワードを直接渡すログインは、SOAP APIのlogin()ではAPIバージョン65.0以降で使えず、OAuthのユーザー名パスワードフローもSummer '23以降に作成された組織では既定でブロックされます
  • 対話的なログインを伴わない自動処理には、OAuth 2.0のJWTベアラーフローが現行の選択肢です
  • JWTの署名(RS256)はVBA単体では作れません。外部のツールやライブラリと組み合わせる前提で設計します
  • REST APIのクエリは/services/data/v67.0/query/?q=の形式で、認証はAuthorization: Bearerヘッダーで行います
  • APIバージョンは古いまま使わず、Summer '26時点の67.0へ上げてください

参考:当時の画面

記事を最初に書いた当時の画面です。いまの手順と違うところは、各画像の説明に書いています。

Excelのメッセージボックスに、ログイン要求のSOAPリクエストXMLが表示されている
当時のログイン要求の中身です。ユーザー名とパスワードの欄はもともと黒く塗られています。
セッションIDとメタデータサーバーURLを表示した2つのメッセージボックス
ログインの戻り値です。セッションIDと接続先URLが取れたことを、ここで確かめていました。
取引先のIdが並ぶQueryResultのXMLがメッセージボックスに表示されている
クエリの応答です。取引先のIdが並んでいれば取得できています。URLのv40.0は現行の版に読み替えてください。

Salesforceの導入・運用についてご相談ください

導入前の検討から、お使いの環境の改修・運用、AIとの連携まで承ります。状況を伺ったうえで、進め方をご提案します。