VBAからBox APIを叩いてみる – IE11廃止対応版

Windows11では既にIE11が使えない為、VBAからのOAuth2.0認証時にIEを立ち上げて認証が出来ない為、こちらのエントリーにあるように「Puppeteerを使って認証するEXE」をNode.jsとPuppeteerを使って作り、クリアさせています。基本的には同じ仕組みなのですが、REST APIを提供するサイトによってちょっとずつ事なるので、困りものですが。

しかし、Windows10でも2022年6月には基本的にIE11が廃止となるため、このままだとBox APIを叩くのに認証が出来ず困ります。という事で、Box API用の認証用EXEを作成し、それをもってしてOAuth2.0を行わせ、Access Tokenを取得するものを作成しました。以下のサイトの改訂版となります。

VBAからBox APIを叩いてみる – 準備編

今回利用するファイル等

上記のファイルに、index.exeというBox API認証用のEXEが入っています。IE11の認証と違って不安定さが無く、また64bit絡みの問題も無いので非常に軽快に動作します。

事前準備

Box APIを利用するためには、Box Developers Portalより事前準備が必要です。また、企業内で利用する場合には、プロキシーサーバを使っているケースがあるので、そのプロキシーサーバのURLとポート番号がアクセスに必要になります。

プロキシー設定を調べる

企業内で使う場合、ウェブアクセスにプロキシーを使ってる場合には、VBAからアクセスする場合もその設定を利用する必要性があります。プロキシーを経由しなければ外に出ることができないので、プログラムが動作しません。プロキシーの設定はいろいろなパターンがありますが、一般的な設定の調べ方は以下の通り。

サーバーのアドレスとポート番号について、http://を除外して、コロンでポート番号でつなげて利用します。(例:hiroproxy.net:8080)

  1. コントロールパネルより「インターネットオプション」を開く
  2. 「接続」タブを開き、「LANの設定」を開く
  3. この画面でプロキシーサーバの部分にアドレスとポート名が入ってるならばこれを控えておく。
  4. 場合によっては、詳細設定の中の「HTTP」で指定してるサーバーアドレスとポート番号を控えておく。
  5. 自動構成スクリプトを使ってる場合、そこに指定されてるアドレスのファイルの中に、様々なプロキシーアドレスが入っていますので、それを一旦ダウンロードして中身をテキストエディタで開いてみる(通常はpacというファイル)
  6. 5.のケースの場合、pacファイル内はIF文を使ってアクセスするサイト別にプロキシーが設定されてることが多いので、もっとも一般的なサイトアクセスもしくはBoxについてだけ定義している場合には、そのサーバーアドレスとポート番号を控えておく。

図:プロキシー設定がない場合はこの作業は不要です。

Box側の設定を行う

Box側ではClient IDやClient Secret等を作る必要性があります。以下の手順でBox Developers Portalにて作成しましょう。

  1. Box Developers Portalにログインする
  2. マイアプリにて「アプリの新規作成」をクリックする
  3. 次の画面では「カスタムアプリ」をクリックし、次へ進みます。
  4. 認証方法のページでは、「標準OAuth2.0」をクリックし、次へ進みます。
  5. アプリの名前は適当に設定し、「アプリの作成」をクリックします。アプリ名は同じものが設定できませんので注意!!
  6. アプリの表示をクリックして設定データを取得しておきます。
  7. OAuth2.0資格情報の欄にて、クライアントIDおよびクライアント機密コード(Secret)をコピーして控えて置きます。
  8. OAuth2.0リダイレクトURIですが、https://localhostでも良いのですが、Internet Explorerを使うので、この設定ですとAccess Tokenが取れない場合があります。(故に今回はこのサイトを指定しました:https://officeforest.org/)
  9. アプリケーションのスコープでは、許可するアクションにチェックを入れます。
  10. CORSドメインはウェブなどで利用する場合に許可送信元として入力する場合にそのサイトのドメインを入れておきます。
  11. 変更を保存するボタンをクリックして完了

図:リダイレクトURLの設定が嵌りどころだったりします。

認証を実行するコード

ここまでの情報でOAuth2.0認証を実行し、Access Token他を取得する準備が整いました。今回はAccessを利用しているので、Access Token、Refresh Token、expireする時間を取得してテーブルに格納します(本来は第三者が容易にこのコードを知られないようにする仕組みを用意しましょう)。IE11で認証するケースとはちょっと異なり、今回はNode.js + Puppeteer + pkgにてWindows用のEXEを作っており、VBAから叩いてAuthcodeを取得する所まではそちらで対応しています。

ソースコード

VBA側コード

  • Authenticate Codeを取得するまでのコードです。getAccessToken関数はこれまでと同じで変わりません
  • Node.jsで作られてるexeに対して、引数で認証用URLとリダイレクトURLの2つを渡し、相手側のプログラムが完了するまで待機させてあります
  • &で引数を区切り渡すと壊れるので、こちらも%26として置き換えて指定(相手側のプログラムでこれは&に変換させています)
  • 出力を受け取ったら、今回はDebug.Printで表示していますが、次の「Access Token」を取得する関数へ渡します。
  • 嵌りポイントとして、Box APIの場合、code=以下を取得するとauthcodeに「LFの改行コード」が混じってしまい、このまま渡すとAccess Tokenが取得出来ないので、改行コードを除去するコードを加えています。

Node.js側コード

今回は、command-line-argsおよびpuppeteer-coreを利用して、VBAからのコマンドライン引数で認証用URLとリダイレクトURLの2つを取得し、PuppeteerでBox APIの認証⇒Authenticate Codeの取得までを担当させています。それ以降はVBA単体で行えます。

Puppeteerで途中でユーザに入力してもらうようにする

  • 今回はコマンドライン引数は、2つ取得させています。
  • 受け取った引数のうち、%26の文字は「&」に変換します。理由はそのままVBA側から&で渡すと引数が壊れる為。
  • 上記ボタンのwaitForSelectorの引数timeout:90000を入れてるのは、デフォルト値だと入力などの時間が足らずに、タイムアウトしやすい為(0だとタイムアウト無しになる)
  • 承認ボタンが押されるまでウェイトを掛ける為に、waitEventにてダミーの関数を割り当てる挙動を入れています。
  • 成功するとリダイレクト先のURLにcode=でAuthenticate Codeが付与されている。このURLは2個目のタブにあるURLなので、allPages[1].url()で取得させています。response.request().redirectChain()などでは取れないので、要注意(responseの中にはそれっぽいURLがいるのだけれど)
  • code=以下を取得させていますが、ここにはLFの改行コードが入ってしまってるので、VBA側で除去させています。
  • 取り出したら、console.logで出力するとVBA側で拾ってくれる

あとは、VBAの側でこのAuthenticate Codeを引き換えにAccess TokenやRefresh Tokenを取得する仕組みに投げて上げれば良い。

pkgコマンドの注意点

前述のNode.jsとPuppeteer-coreで作ったアプリをEXE化するものとして、pkgを利用しています。類似のものにnexeがあります。最新版pkgでは、Node.js v14に対応しているものの、別の環境でビルドをしようとしたらGitやらpatch.exeやらNASMやらが入っていないとエラー?になった為、ちょっと癖があるプログラムです。

よって、今回はpkg@5.3.3およびNode.js 14.17.5でビルドしています。ビルドする時は以下のコマンドでビルドしないと、evaluate関数あたりでエラーが出てしまうので、注意。

作成してできたindex.exeをindex-win.exeにリネームして今回のVBAからは呼び出させています。

nexeコマンドの注意点

同じくEXEを作るnexeですが、keytarなどのネイティブモジュールをパックしてくれなくなってしまったのと、インストール自体がかなり面倒な事になっていたので、改めてここにインストール方法とビルドの注意点を。

注意点としてv3.3.3の時点では

  • nexeは自身が用意してる版のNode.jsでしか対応していないので、ビルドする場合にはNode.jsのバージョンを合わせる必要があります(現時点では、v14.15.3まで対応)
  • コマンドラインは、nexe index.jsでビルドが出来ます。
  • プロキシがある場合には、実行する為にnexeがプロキシを透過できるようにする必要があります以下のコマンドを入れて、npmにプロキシ通過の設定をしておくこと
  • keytarなどのネイティブモジュールはEXEにパックされないので、node_modulesのフォルダ毎作成したexeの配布が必要。但し、node_modulesの中はkeytarのフォルダのみあればOK

また、command-line-argsなどにコマンドラインパラメータを渡すようなケースでは、VBAで使う場合はメアド、URLなどの文字列は必ず、Chr(34)などで対象の文字列を括ってからでないと、Account is Requiredというエラーが出て止まります(keytarが原因)。

認証を実行する

ここまでで、OAuth2.0認証のAuthenticate Codeの取得までが装備出来ているので、VBA側で「BoxAuthorization」を実行します。今回のは認証までのコードのみしか入っていませんが、ソレ以降のBox APIを叩くコードやrefresh tokenでAccess Tokenを交換するコードはこれまでと同じです。

実行すると

  1. 用意しておいた認証用URLとリダイレクトURLをindex.exeに引き渡す
  2. Puppeteerにてインストール済みのChromeもしくはChromium Edgeが起動し認証ページが開かれる
  3. ログインをして、承認を実行する
  4. リダイレクトURL先にcode=付きのURLで飛ばされて、Authenticate Codeを取り出す

という作業が行われます

図:承認画面

関連リンク

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください。