OAuth認証を自作する!(php+twitter)
ライブラリを使うのも良いですが、ちゃんとトラブル解決ができるように、
OAuth認証を自作してみました。ここでも、twitterのお世話にw
ユーザーから見える画面として、まずは
http://toridge.sakura.ne.jp/oauth/oauth_twitter.phpを体験して下さい。
■■■ 処理フロー ■■■
<前準備>
1)アプリケーションの登録画面(http://twitter.com/oauth_clients)で、
アプリの登録。customer_keyとcustomer_secretを取得。
(type:browser、callbackURL:http://~oauth_twitter_callback.php、ReadWrite)
<アプリ処理>
2)customer_keyと、customer_secretからリクエストトークン(token、secret_token)の取得。
3)リクエストトークンをGET値として、twitter画面へ遷移。
(http://twitter.com/oauth/authenticate?リクエストで取得したtoken値)
<ユーザーが許可後、処理>
4)callbackに指定したURLへoauth_verifierがGETとして渡され遷移。
5)リクエストトークン(token、secret_token)とoauth_verifier、およびcustomer_keyとcustomer_secretから、oauth_tokenと、oauth_token_secretを取得する。この値を用いてコンテンツへアクセスができるようになる。
■■■ 説明 ■■■
まずは、2)のcustomer_keyとcustomer_secretから、リクエストトークン(tokenとsecret_token)を得るには、
‘oauth_consumer_key’ =>アプリ登録時取得
‘oauth_signature_method’ => 暗号化方法twitterでは’HMAC-SHA1′
‘oauth_signature’ => ※暗号に使う。後で解説。
‘oauth_timestamp’ => タイムスタンプ
‘oauth_nonce’ => ユニークコード
‘oauth_version’ => ’1.0′
‘oauth_callback’ => アプリ登録時のcallbackURLと同じ。
※’oauth_callback’がないとcallbackがうまく動きません。
下記は、このパラメータを作成し、GETで渡す値にするまでの関数を添付。
みてわかると通り、ほぼ’oauth_signature’ を作るために尽力しますw。
簡単に説明すると、’oauth_signature’ 以外の値をエンコードし、自然順にソート。GET値のように連結。リクエストを送るURLと、メソッドのGET、連結したパラメータを再度、エンコードし&で連結(base_stringの完成)。customer_secretから、hash(暗号化)用の鍵を用意。この鍵を用いて、
base_stringをhashし、base64にエンコードすれば、oauth_signatureの完成。この値を含めたパラメータ値をGETとして連結する関数です(長いw)。
これを関数化しているのは、5)のoauth_tokenと、oauth_token_secretを得るのにも使うためです。このときは、hashの鍵としてtoken_secretとcustomer_secretの両方をつかます。
一直線なプログラムですので、追ってみてください。
すべてのソースは、callback後のページで、公開しておきますので、上のoauthリンクを試してみてくださいw。
■■■ 以下、パラメータ作成関数のソース ■■■
function get_parameters($token = '',$verifier = '',$secret = '',$call = 'oauth/request_token')
{
//準備(パラメーターの設定)
include_once('oauth_twitter_config.php');//config:設定値の呼び出し
$callbackurl=OAUTH_CALLBACK;
$url = "http://twitter.com/".$call;
$method = "GET";
$key = CONSUMER_KEY;
$customer_secret = CONSUMER_SECRET;
$parameters = array('oauth_consumer_key' => $key,
‘oauth_signature_method’ => ‘HMAC-SHA1′,//twitterは’HMAC-SHA1′のみ。
‘oauth_signature’ => $secret,//methodが’PLAINTEXT’の場合はsecretが値になる。
‘oauth_timestamp’ => time(),
‘oauth_nonce’ => md5(microtime() . mt_rand()),
‘oauth_version’ => ’1.0′
);
if ($token!=”") {
$parameters['oauth_token'] = $token;
}
if($verifier!=”"){
$parameters['oauth_verifier'] = $verifier;
}
if ($call==’oauth/request_token’ && $callbackurl!=”") {
$parameters['oauth_callback'] = $callbackurl;
}
//エンコード関数
function urlencoderfc3986($input){
return str_replace(‘+’,’ ‘,str_replace(‘%7E’, ‘~’, rawurlencode($input)));
}
// oauth_signature の初期化 #1
if (isset($parameters['oauth_signature'])) {
unset($parameters['oauth_signature']);
}
// URLエンコード(パラメータ) #2
$params = array_map(“urlencoderfc3986″, $parameters);
// 自然順にソート (natsort) #3
uksort($params, ‘strnatcmp’);
//”key”=”value”&・・・の連結 #4
$pairs = array();
foreach ($params as $key => $value) {
$pairs []= $key.’=’.$value;
}
$param = implode(‘&’,$pairs);
//エレメント(メソッド、URL、パラメータ)の連結 #5
$parts = array(
$method,
$url,
$param
);
// Urlエンコード(エレメント)#6
$parts = array_map(‘urlencodeRFC3986′, $parts);
//&で連結し base_string の完成 #7
$part=implode(‘&’,$parts);
//ready hash_hmac 鍵の準備 #8
$key_parts = array(
$customer_secret,
($secret)?$secret:”"
);
// Urlエンコード(hash用の鍵)#9
$key_parts = array_map(“urlencodeRFC3986″, $key_parts);
$key = implode(‘&’, $key_parts);
//hash_hmac と base64_encode を行ない oauth_signatureの生成 #10
$part_hash=base64_encode( hash_hmac(‘sha1′, $part, $key, true));
$parameters['oauth_signature']=$part_hash;
// URLエンコード(パラメータ)完成版 #11
$parameters_encd = array_map(“urlencoderfc3986″,$parameters);
//パラメータ完成版の”key”=”value”&・・・の連結 #12
$parameter_pairs = array();
foreach ($parameters_encd as $key => $value) {
$parameter_pairs []= $key.’=’.$value;
}
$q = implode(‘&’,$parameter_pairs);
return $q;
}
?>