OAuth認証を行うVBAを記述する

以上で、OAuth認証を行うための道具が揃いましたので、Webサービスを利用するためのアクセス・トークン、アクセス・シークレットを取得するまでのVBAを実装しましょう。まず、OAuth認証の流れをおさらいしておきます。

(1)リクエスト・トークンを要求して取得する
(2)取得したリクエスト・トークンをユーザーに認証してもらう
(3)アクセス・トークンを要求して取得する

という流れでした(図8)。

図8.OAuth認証の流れ

このVBAは、「認証する」ボタンをクリックした時のコードとして記述しますので、ワークシートに戻ります。任意のセルをクリックしてオブジェクトの選択状態が解除されていることを確認し、[開発]タブの[デザインモード]がONの状態で、コマンドボタン「cbAuth」をダブルクリックします。VBエディタが開きますので、Private Sub cbAuth_Click()の中に、コードを記述していきます。

[リスト7]OAuth認証を行うVBA

Private Sub cbAuth_Click()

    'トークン、シークレット受け取り用変数
    Dim strRes As String, resPrm() As String, resPrmKeyVal() As String
    Dim i As Integer

    '(1)リクエスト・トークン要求(フェーズ1)
    Set param = New Scripting.Dictionary '連想配列オブジェクトの生成
    SetParam 1 '(1-1)OAuth特有のパラメータ設定
    MakeSign 1, "POST", Range("urlRequestToken") '(1-2)電子署名の作成
    Set xmlhttp = New MSXML2.xmlhttp 'HTTP通信用オブジェクトの生成
    SendHttp "POST", Range("urlRequestToken") '(1-3)HTTP送信
    If Range("OAuthStatus") <> "OK" Then
        MsgBox ("認証に失敗しました。" & Range("OAuthStatus"))
        Set param = Nothing '連想配列オブジェクトの解放
        Set xmlhttp = Nothing 'HTTP通信用オブジェクトの解放
        Exit Sub
    End If
    strRes = xmlhttp.responseText 'レスポンスを格納
    Set param = Nothing '連想配列オブジェクトの解放
    Set xmlhttp = Nothing 'HTTP通信用オブジェクトの解放
    'リクエスト・トークンとリクエスト・シークレットを取得
    resPrm = Split(strRes, "&")
    For i = 0 To UBound(resPrm)
        resPrmKeyVal = Split(resPrm(i), "=")
        Select Case resPrmKeyVal(0)
            Case "oauth_token"
                Range("request_token") = resPrmKeyVal(1)
            Case "oauth_token_secret"
               Range("request_secret") = resPrmKeyVal(1)
        End Select
    Next

    '(2)ユーザーに認証してもらう
    '(2-1)ブラウザを起動し、ユーザーにアプリを認証してもらうページを表示
    Dim objIE As Object 'Internet Explorerを起動するためのオブジェクト変数
    Set objIE = CreateObject("InternetExplorer.application")
    objIE.Visible = True
    objIE.navigate Range("urlUserAuthorize") & Range("request_token")
    Set objIE = Nothing 'オブジェクトの解放

    '(2-2)認証後、ブラウザに表示されたPINコードを入力してもらう
    Range("pinCode") = InputBox("ブラウザに表示されたPINコードを入力してください")

    '(3)アクセス・トークン要求(フェーズ2)
    Set param = New Scripting.Dictionary '連想配列オブジェクトの生成
    SetParam 2 '(3-1)OAuth特有のパラメータ設定
    MakeSign 2, "POST", Range("urlAccessToken") '(3-2)電子署名の作成
    Set xmlhttp = New MSXML2.xmlhttp 'HTTP通信用オブジェクトの生成
    SendHttp "POST", Range("urlAccessToken") '(3-3)HTTP送信
    If Range("OAuthStatus") <> "OK" Then
        MsgBox ("認証に失敗しました。" & Range("OAuthStatus"))
        Set param = Nothing '連想配列オブジェクトの解放
        Set xmlhttp = Nothing 'HTTP通信用オブジェクトの解放
        Exit Sub
    End If
    strRes = xmlhttp.responseText 'レスポンスを格納
    Set param = Nothing '連想配列オブジェクトの解放
    Set xmlhttp = Nothing 'HTTP通信用オブジェクトの解放
    'アクセス・トークンとアクセス・シークレットを取得
    resPrm = Split(strRes, "&")
    For i = 0 To UBound(resPrm)
        resPrmKeyVal = Split(resPrm(i), "=")
        Select Case resPrmKeyVal(0)
            Case "oauth_token"
                Range("access_token") = resPrmKeyVal(1)
            Case "oauth_token_secret"
                Range("access_secret") = resPrmKeyVal(1)
        End Select
    Next

    MsgBox ("認証に成功しました。")

End Sub

(1)リクエスト・トークン要求

まず、OAuth引数設定用の連想配列オブジェクトparamを生成し、プロシージャsetParamをフェーズ1として呼び出して、引数を設定しています(1-1)。次に、プロシージャmakeSignをフェーズ1、POSTメソッド、リクエスト・トークン要求先URLを渡して呼び出して、電子署名を作成しています(1-2)。そして、HTTP通信用オブジェクトxmlhttpを生成し、プロシージャsendHttpをPOSTメソッド、リクエスト・トークン要求先URLを渡して呼び出し、リクエストを送信しています(1-3)。

sendHttpの中で「OAuthStatus」セルに設定された送信結果を見て、OKでなかったら警告ダイアログを出して、終了します。

OKなら、xmlhttpオブジェクトのresponseTextプロパティを参照して、レスポンスを文字列変数strResに格納し、用済みのオブジェクトparam、xmlhttpにNothingをセットして解放します。

レスポンスには「oauth_token=リクエスト・トークン&oauth_token_secret=リクエスト・シークレット」という形の文字列が格納されますので、まずSplit関数を使って「&」で分解し、resPrm配列に格納します。resPrm配列の各要素を走査し、Split関数を使って「=」で分解した左側がoauth_tokenだったら、右側の文字列をリクエスト・トークン用セルに格納します。同様に、左側がoauth_token_secretだったら、右側の文字列をリクエスト・シークレット用セルに格納します。

(2)ユーザーに認証してもらう

(2-1)でInternet Explorerを起動し、ユーザーに認証してもらうページのURLへ移動すると、図9のようなページが表示されます。

ユーザーがTwitterに最近ログインしていない場合は、ログインIDとパスワードも要求されます。

図9.アプリを認証してもらうページ

ユーザーが「認証する」ボタンをクリックすると、PINコードを表示した図10のようなページが表示されます。

図10.PINコード表示ページ

このPINコードをInputBox経由で入力してもらいます。

図11.InputBoxダイアログ

PINコードを表示したページは閉じてしまって構いません。

(3)アクセス・トークン要求

まず、OAuth引数設定用の連想配列オブジェクトparamを生成し、プロシージャsetParamをフェーズ2として呼び出して、引数を設定しています(3-1)。次に、プロシージャmakeSignをフェーズ2、POSTメソッド、アクセス・トークン要求先URLを渡して呼び出して、電子署名を作成しています(3-2)。そして、HTTP通信用オブジェクトxmlhttpを生成し、プロシージャsendHttpをPOSTメソッド、アクセス・トークン要求先URLを渡して呼び出し、リクエストを送信しています(3-3)。 sendHttpの中で「OAuthStatus」セルに設定された送信結果を見て、OKでなかったら警告ダイアログを出して、終了します。 OKなら、レスポンスをxmlhttpオブジェクトから文字列変数strResに格納し、用済みのオブジェクトparam、xmlhttpにNothingをセットして解放します。

レスポンスには「oauth_token=アクセス・トークン&oauth_token_secret=アクセス・シークレット」という形の文字列が格納されますので、まずSplit関数を使って「&」で分解し、resPrm配列に格納します。resPrm配列の各要素を走査し、Split関数を使って「=」で分解した左側がoauth_tokenだったら、右側の文字列をアクセス・トークン用セルに格納します。同様に、左側がoauth_token_secretだったら、右側の文字列をアクセス・シークレット用セルに格納します。

以上で、アクセス・トークンとアクセス・シークレットが取得できました。

まとめ

OAuth認証は難しかったですか。Amazon Webサービスなどでも必要になりますので、概要だけでも把握しておいてください。 次回は、今回取得したアクセス・トークンを使って、Twitterへツイートを投稿したり、タイムラインを取得したりする方法を説明します。お楽しみに。

WINGSプロジェクト 遠藤 存著/山田祥寛監修
WINGS プロジェクトについて
テクニカル執筆プロジェクト(代表山田祥寛)。海外記事の翻訳から、主にWeb開発分野の書籍・雑誌/Web記事の執筆、講演等を幅広く手がける。2011年5月時点での登録メンバは35名で、現在も一緒に執筆をできる有志を募集中。