アクセストークンを取得する「その3」の目標にしましょう。
前回のソースをrequestkey.phpというファイル名で保存したとします。そうするとページの遷移は
サービスの解説ページ等
↓
https://net.pressmantech.com/twitter/requestkey.php(前回までの作成したプログラム)
↓ [自動でリダイレクト]
https://api.twitter.com/oauth/authorize?oauth_token=8SjpidnOC8X8cgDmy3hQsYKo3R21Bxc8OvcwlYW6hg(twitterの認証画面)
↓ ["アプリを認証"ボタンを押下するとコールバックURLにリダイレクト]
https://net.pressmantech.com/twitter/access.php?oauth_token=8SjpidnOC8X8cgDmy3hQsYKo3R21Bxc8OvcwlYW6hg&oauth_verifier=NhFhj2BF8gAdMWh8vbvChDxuU6kPhPsc4MKhBPwpM6s
となります。リクエストトークンをユーザーに認証してもらうとコールバックURLへoauth_token,oauth_verifierの二つのパラメーターとともにリダイレクトされます。これらを使ってアクセスキーを手に入れたいと思います。
プログラムの流れとしてはリクエストキトークンを要求したのと9割方同じになります。パラメータと秘密鍵から署名を作ってサーバーと通信といった具合です。そのため、本来ならOAuth用のクラスを作るべきなのでしょうがOAuthの流れを理解するのが目的なのでコピペプログラムで行きます。
やることといったらAuthorizationヘッダに入る値が増えたくらいでリクエストトークンのときとほぼ同じです。
署名を作る部分が面倒なだけでそれさえ書いてしまい使いまわせばプログラム自体はそれほど難しいものではありません。
そんなわけで処理内容に関してあれこれ書きませんのでソースを見てください。
これで、アクセストークンを取得できたのであとはこれを使ってユーザーのデータにアクセスします。それは次回に回してOAuth1.0について一言。
トークンシークレットってなにそれ美味しいの?
どうしてもトークンシークレットに存在意義が見出せません。コンシューマシークレットを使って署名を作るんだからなくても良いじゃんって気がします。OAuth2.0なんてSSL使う前提でトークンシークレットどころか署名すらなくしちゃってますしね。
<?php
$oauthConfig = array( 'callbackUrl' =--> 'http://net.pressmantech.com/',
'authorizeUrl' => 'https://api.twitter.com/oauth/authorize',
'requestTokenUrl' => 'https://api.twitter.com/oauth/request_token',
'accessTokenUrl' => 'https://api.twitter.com/oauth/access_token',
'consumerKey' => 'pD4dm6IQHa6jhtge82Fg',
'consumerSecret' => 'BfTtokF9bfb5Fim6BsPaEg9Fo3y4FM6kPlCQQiRPKA4'
);
/**
* (0)リダイレクトURLについてきたパラメータを取得
*/
$oauthToken = $_GET['oauth_token'];
$oauthVerifier = $_GET['oauth_verifier'];
session_start();
$requestToken = unserialize($_SESSION['TWITTER_REQUEST_TOKEN']);
$method = 'POST';
$nonce = md5(uniqid(rand(), true));
$timestamp = time();
$authorization = array(
'oauth_nonce' => $nonce,
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_timestamp' => $timestamp,
'oauth_consumer_key' => $oauthConfig['consumerKey'],
//↓リクエストトークンの時にはない値
'oauth_token' => $requestToken['oauth_token'],
//↓リクエストトークンの時にはない値
'oauth_verifier' => $oauthVerifier,
'oauth_version' => '1.0'
);
ksort($authorization);
$signatureBaseString = '';
foreach($authorization as $key => $val){
$signatureBaseString .= $key . '=' . rawurlencode($val) . '&';
}
$signatureBaseString = substr($signatureBaseString,0,-1);
$signatureBaseString = $method
. '&' . rawurlencode($oauthConfig['accessTokenUrl'])
. '&' . rawurlencode($signatureBaseString);
/**
* (1)リクエストトークンのときはoauth_token_secretが無かったが
* 今回は取得できているので付ける
*/
$signingKey = rawurlencode($oauthConfig['consumerSecret'])
. '&' . rawurlencode($requestToken['oauth_token_secret']);
$authorization['oauth_signature'] = base64_encode(hash_hmac('sha1',$signatureBaseString,$signingKey,true));
$oauthHeader = 'OAuth ';
foreach($authorization as $key => $val){
$oauthHeader .= $key . '="' . rawurlencode($val) .'",';
}
$oauthHeader = substr($oauthHeader,0,-1);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $oauthConfig['accessTokenUrl']);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization :' . $oauthHeader,
'Content-Length:',
'Expect:',
'Content-Type:')
);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POST, true);
$response = curl_exec($curl);
$accessToken = array();
foreach(explode('&',$response) as $v){
$param = explode('=',$v);
$accessToken[$param[0]] = $param[1];
}
/**
* (2)アクセストークンはユーザーデータにアクセスするときに常に必要になるので
* セッションやDBに保存しておく
*/
$_SESSION['TWITTER_ACCESS_TOKEN'] = serialize($accessToken);
/**
* (3)すでにアクセストークンを取得できているのでサービスを提供するページへ
* リダイレクトする等する。
* とりあえずここではtwitterのサーバーからのレスポンスを表示している。
*/
print $response;