PHP+VBS : デスクトップアプリで Twitter API のアクセストークンを取得


  WEBアプリとは多少手順が変わります




WEB アプリでは、データのやり取りを リダイレクトを使ってユーザに手間がかからないようにしますが、デスクトップで動くアプリケーション( この場合は VBScript(WSH) ) では、途中でブラウザ使用して、Twitter のサイトにアクセスし、暗証番号( PIN ) を取得して、それをデスクトップアプリケーションに引き渡す必要があります。

これは、WEB アプリケーションで、oauth_verifier として取得していたものですが、この場合は人が暗記するかクリップボードにコピーする事になるので、桁数の少ない数字となります。

Twitter_pin

Twitter_pin2

さらに、Twitter に対する認証処理は、クライアントからでも良いのですが、元となるアプリケーションのキーとパスワードを公開するわけにはいかないので、アクセストークンを取得する部分の処理を PHP としてホスティングします。

アクセストークン( 秘密のフクセストークンも含む )は、ローカルの PC に保存する事となりますが、そのトークンをキャンセルしたい場合は、自分の Twitter ユーザに登録されている 該当アプリを削除すれば OK です。ですが、そういう内容のものなので、自宅でのみ使う事ように「警告」した上で公開する必要は出てきます。


関連する記事


  PHP ( ホスト側のコード )




プロセスが途中でユーザの手作業が入るので、二つ必要になります

※ 引き渡すデータは単純なテキストで返しています( XML や JSON を使うほどでも無いので )
※ テストは localhost で問題ありません


phase_1.php
<?
// **********************************************************
// Acquiring a request token
// **********************************************************
header( "Content-Type: text/html; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

// **********************************************************
// OAuth 用の urlencode 関数
// **********************************************************
function url_rfc3986( $str ) {
	// php 5.3.x 〜 ではこの変換は必要無い
	return str_replace('%7E', '~', rawurlencode($str));
}

// **********************************************************
// API ( SSL is recommended )
// **********************************************************
$twitter_url = 'https://api.twitter.com/oauth/request_token';

// **********************************************************
// 認証データ
// **********************************************************
$oauth_consumer_key = "Consumer key"; 
$oauth_consumer_secret = "Consumer secret"; 
$oauth_token = "";
$oauth_secret = "";

// 毎回変化するランダムな文字列
$mt = microtime();
$rand = mt_rand();
$oauth_nonce = md5($mt . $rand);

$oauth_signature_method = "HMAC-SHA1";
$oauth_timestamp = mktime();

$oauth_version = "1.0";

// コールバック url
$oauth_callback = "oob";

// *********************************************************
// シグネチャ用ベース文字列作成
/*
  httpMethod + "&" +
  url_encode(  base_uri ) + "&" +
  sorted_query_params.each  { | k, v |
      url_encode ( k ) + "%3D" +
      url_encode ( v )
  }.join("%26")
*/
// *********************************************************
$base_string = "POST";
$base_string .= "&" . url_rfc3986($twitter_url);
$base_string .= "&";

$base_string .= url_rfc3986("oauth_callback")."%3D".url_rfc3986(url_rfc3986($oauth_callback))."%26";
$base_string .= url_rfc3986("oauth_consumer_key")."%3D".url_rfc3986($oauth_consumer_key)."%26";
$base_string .= url_rfc3986("oauth_nonce")."%3D".url_rfc3986($oauth_nonce)."%26";
$base_string .= url_rfc3986("oauth_signature_method")."%3D".url_rfc3986($oauth_signature_method)."%26";
$base_string .= url_rfc3986("oauth_timestamp")."%3D".url_rfc3986($oauth_timestamp)."%26";
$base_string .= url_rfc3986("oauth_version")."%3D".url_rfc3986($oauth_version);

// *********************************************************
// シグネチャ作成
/*
url_encode( consumer_secret ) + "&" +
url_encode( oauth_token_secret || nil )
*/
// *********************************************************
$oauth_signature = 
base64_encode( hash_hmac(
	"sha1",
	$base_string,
	url_rfc3986($oauth_consumer_secret) . "&",
	true
));
//$postfields['oauth_signature'] = $oauth_signature;

// *********************************************************
// curl 処理
// *********************************************************
$curl = curl_init();
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $twitter_url);
curl_setopt($curl, CURLOPT_POST, 1);

// *********************************************************
// http ヘッダ作成
// *********************************************************
$header = array();
$header[] = 'Expect:';

$header[] = 'Authorization: OAuth '.
url_rfc3986("oauth_nonce")."=\"".url_rfc3986($oauth_nonce)."\",".
url_rfc3986("oauth_callback")."=\"".url_rfc3986($oauth_callback)."\",".
url_rfc3986("oauth_signature_method")."=\"".url_rfc3986($oauth_signature_method)."\",".
url_rfc3986("oauth_timestamp")."=\"".url_rfc3986($oauth_timestamp)."\",".
url_rfc3986("oauth_consumer_key")."=\"".url_rfc3986($oauth_consumer_key)."\",".
url_rfc3986("oauth_signature")."=\"".url_rfc3986($oauth_signature)."\",".
url_rfc3986("oauth_version")."=\"".url_rfc3986($oauth_version)."\"";

curl_setopt($curl, CURLOPT_HTTPHEADER, $header);

// *********************************************************
// https 用
// *********************************************************
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);

// *********************************************************
// 送信
// *********************************************************
$result = curl_exec($curl);


// *********************************************************
// 結果
// *********************************************************

if($result === false) {
	echo 'Curl error: ' . curl_error($curl);
	exit();
}
else {
//	echo 'Operation completed without any errors';
}
curl_close($curl);

parse_str($result,$arr);
print $arr['oauth_token_secret'] . "\n";
print "https://twitter.com/oauth/authorize?oauth_token={$arr['oauth_token']}\n";

?>



phase_2.php
<?
header( "Content-Type: text/html; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );
// **********************************************************
// AOuth 用の urlencode 関数
// **********************************************************
function url_rfc3986( $str ) {
	// php 5.3.x 〜 ではこの変換は必要無い
	return str_replace('%7E', '~', rawurlencode($str));
}

// **********************************************************
// API ( SSL is recommended )
// **********************************************************
$twitter_url = 'https://api.twitter.com/oauth/access_token';

// **********************************************************
// 認証データ
// **********************************************************
$oauth_consumer_key = "Consumer key"; 
$oauth_consumer_secret = "Consumer secret"; 
$oauth_token = $_GET['oauth_token'];
$oauth_secret = $_GET['oauth_token_secret'];

// 毎回変化するランダムな文字列
$mt = microtime();
$rand = mt_rand();
$oauth_nonce = md5($mt . $rand);

$oauth_signature_method = "HMAC-SHA1";
$oauth_timestamp = mktime();

$oauth_version = "1.0";

// *********************************************************
// シグネチャ用ベース文字列作成
/*
  httpMethod + "&" +
  url_encode(  base_uri ) + "&" +
  sorted_query_params.each  { | k, v |
      url_encode ( k ) + "%3D" +
      url_encode ( v )
  }.join("%26")
*/
// *********************************************************
$base_string = "POST";
$base_string .= "&" . url_rfc3986($twitter_url);
$base_string .= "&";

$base_string .= url_rfc3986("oauth_consumer_key")."%3D".url_rfc3986($oauth_consumer_key)."%26";
$base_string .= url_rfc3986("oauth_nonce")."%3D".url_rfc3986($oauth_nonce)."%26";
$base_string .= url_rfc3986("oauth_signature_method")."%3D".url_rfc3986($oauth_signature_method)."%26";
$base_string .= url_rfc3986("oauth_timestamp")."%3D".url_rfc3986($oauth_timestamp)."%26";
$base_string .= url_rfc3986("oauth_token")."%3D".url_rfc3986($oauth_token)."%26";
$base_string .= url_rfc3986("oauth_verifier")."%3D".url_rfc3986($_GET['oauth_verifier']);
$base_string .= url_rfc3986("oauth_version")."%3D".url_rfc3986($oauth_version);

// *********************************************************
// シグネチャ作成
/*
url_encode( consumer_secret ) + "&" +
url_encode( oauth_token_secret || nil )
*/
// *********************************************************
$oauth_signature = 
base64_encode( hash_hmac(
	"sha1",
	$base_string,
	url_rfc3986($oauth_consumer_secret) . "&" . url_rfc3986($oauth_secret),
	true
));
//$postfields['oauth_signature'] = $oauth_signature;

// *********************************************************
// curl 処理
// *********************************************************
$curl = curl_init();
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $twitter_url);
curl_setopt($curl, CURLOPT_POST, 1);

// *********************************************************
// http ヘッダ作成
// *********************************************************
$header = array();
$header[] = 'Expect:';
$header[] = 'Authorization: OAuth '.
url_rfc3986("oauth_consumer_key")."=\"".url_rfc3986($oauth_consumer_key)."\",".
url_rfc3986("oauth_nonce")."=\"".url_rfc3986($oauth_nonce)."\",".
url_rfc3986("oauth_signature_method")."=\"".url_rfc3986($oauth_signature_method)."\",".
url_rfc3986("oauth_timestamp")."=\"".url_rfc3986($oauth_timestamp)."\",".
url_rfc3986("oauth_token")."=\"".url_rfc3986($oauth_token)."\",".
url_rfc3986("oauth_verifier")."=\"".url_rfc3986($_GET['oauth_verifier'])."\",".
url_rfc3986("oauth_signature")."=\"".url_rfc3986($oauth_signature)."\",".
url_rfc3986("oauth_version")."=\"".url_rfc3986($oauth_version)."\"";

curl_setopt($curl, CURLOPT_HTTPHEADER, $header);

// *********************************************************
// https 用
// *********************************************************
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);

// *********************************************************
// 送信
// *********************************************************
$result = curl_exec($curl);

// *********************************************************
// 結果
// *********************************************************

if($result === false) {
	echo 'Curl error: ' . curl_error($curl);
	exit();
}
else {
//	echo 'Operation completed without any errors';
}
curl_close($curl);

parse_str($result,$arr);
print $arr['oauth_token'] . "\n";
print $arr['oauth_token_secret'] . "\n";

?>



  VBScript : クライアントアプリケーション( アクセストークンの取得 )

取得したトークンはテキストファイルに出力しています。実際の処理を行うアプリケーションが
このトークンを使う事になりますので、このコードはその前処理のようなものです。


GetAccessToken.wsf
<JOB>
<OBJECT id="WshShell" progid="WScript.Shell" />
<OBJECT id="Fso" progid="Scripting.FileSystemObject" />
<OBJECT id="objHTTP" progid="MSXML2.XMLHTTP" />

<SCRIPT language=VBScript>
' **********************************************************
' 暗証番号( PIN ) を手に入れる為の URL を取得する
'
' 取得用 URL ( アプリケーションのユーザが用意する )
' **********************************************************
phase_1_url = "http://............/phase_1.php"

' *********************************************************
' 送信準備
' *********************************************************
Call objHTTP.Open( "GET",phase_1_url, False )

' *********************************************************
' 送信
' *********************************************************
Call objHTTP.Send(strData)

' *********************************************************
' URL を取得
' *********************************************************
aRet = Split(objHTTP.responseText,vbLf)

if Ubound(aRet) < 2 then
	Wscript.Echo aRet(0)
	Wscript.Quit
end if

' *********************************************************
' IE で URL にアクセス
' *********************************************************
WshShell.Run( "iexplore.exe " & aRet(1) )

' **********************************************************
' 一時トークン保存
' **********************************************************
Set OutObj1 = Fso.OpenTextFile( "token1.log", 2, True )
Set OutObj2 = Fso.OpenTextFile( "token2.log", 2, True )
aData = Split(aRet(1),"=")
OutObj1.Write aData(1)
OutObj2.Write aRet(0)
OutObj2.Close
OutObj1.Close

PIN = InputBox("暗証番号( PIN )を入力して下さい")

' **********************************************************
' 取得用 URL ( アプリケーションのユーザが用意する )
' **********************************************************
phase_2_url = "http://............/phase_2.php?"
phase_2_url = phase_2_url & "oauth_token=" & aData(1)
phase_2_url = phase_2_url & "&oauth_token_secret=" & aRet(0)
phase_2_url = phase_2_url & "&oauth_verifier=" & PIN

' *********************************************************
' 送信準備
' *********************************************************
Call objHTTP.Open( "GET",phase_2_url, False )

' *********************************************************
' 送信
' *********************************************************
Call objHTTP.Send(strData)

' *********************************************************
' URL を取得
' *********************************************************
aRet = Split(objHTTP.responseText,vbLf)

if Ubound(aRet) < 2 then
	Wscript.Echo aRet(0)
	Wscript.Quit
end if

' **********************************************************
' トークン保存
' **********************************************************
Set OutObj1 = Fso.OpenTextFile( "token1.log", 2, True )
Set OutObj2 = Fso.OpenTextFile( "token2.log", 2, True )
OutObj1.Write aRet(0)
OutObj2.Write aRet(1)
OutObj2.Close
OutObj1.Close

WScript.Echo "処理が終了しました"


</SCRIPT>
</JOB>







yahoo  google  MSDN  MSDN(us)  WinFAQ  Win Howto  tohoho  ie_DHTML  vector  wdic  辞書  天気 


[sh_web]
CCBot/2.0 (http://commoncrawl.org/faq/)
17/08/21 22:44:33
InfoBoard Version 1.00 : Language=Perl

BatchHelper COMprog CommonSpec Cprog CprogBase CprogSAMPLE CprogSTD CprogSTD2 CprogWinsock Cygwin GameScript HTML HTMLcss InstallShield InstallShieldFunc JScript JScriptSAMPLE Jsfuncs LLINK OldProg OracleGold OracleSilver PRO PRObrowser PROc PROconePOINT PROcontrol PROftpclient PROjscript PROmailer PROperl PROperlCHAT PROphp PROphpLesson PROphpLesson2 PROphpLesson3 PROphpfunction PROphpfunctionArray PROphpfunctionMisc PROphpfunctionString PROsql PROvb PROvbFunction PROvbString PROvbdbmtn PROvbonepoint PROwebapp PROwin1POINT PROwinSYSTEM PROwinYOROZU PROwindows ProjectBoard RealPHP ScriptAPP ScriptMaster VBRealtime Vsfuncs a1root access accreq adsi ajax amazon argus asp aspSample aspVarious aspdotnet aw2kinst cappvariety centura ckeyword classStyle cmaterial cmbin cmdbapp cmenum cmlang cmlistbox cmstd cmstdseed cmtxt cs daz3d db dbCommon dbaccess dnettool dos download flex2 flex3 flex4 framemtn framereq freeWorld freesoft gimp ginpro giodownload google hdml home hta htmlDom ie9svg install java javaSwing javascript jetsql jquery jsp jspTest jspVarious lightbox listasp listmsapi listmsie listmsiis listmsnt listmspatch listmsscript listmsvb listmsvc memo ms msde mysql netbeans oraPlsql oracle oracleWiper oraclehelper orafunc other panoramio pear perl personal pgdojo pgdojo_cal pgdojo_holiday pgdojo_idx pgdojo_ref pgdojo_req php phpVarious phpguide plsql postgres ps r205 realC realwebapp regex rgaki ruby rule sboard sc scprint scquest sdb sdbquest seesaa setup sh_Imagick sh_canvas sh_dotnet sh_google sh_tool sh_web shadowbox shgm shjquery shvbs shweb sjscript skadai skywalker smalltech sperl sqlq src systemdoc tcpip tegaki three toolbox twitter typeface usb useXML vb vbdb vbsfunc vbsguide vbsrc vpc wcsignup webanymind webappgen webclass webparts webtool webwsh win8 winofsql wmi work wp youtube