OAuth署名生成 PHP実装サンプル

OAuth署名生成 PHP実装サンプル

OAuth署名生成のPHPによる実装サンプルを以下に示します。

/**
 * OAuth HMAC-SHA1方式の署名を作成する.
 *
 * @param string http_method HTTPメソッドを指定
 * @param array parameter   クエリパラメータとOAuthパラメータをマージしたもの
 * @param string uri                実際にリクエストするURI(リクエストパラメータは含めない)
 * @param string secret          秘密鍵
 *
 * @return string 作成した署名。作成失敗した場合はNULL
 */
function make_signature_hmac($http_method, $parameter, $uri, $secret)
{
 // http_method
 $http_method = strtoupper($http_method);
 
 // uri
 $parts = parse_url($uri);
 $scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http';
 $port = (isset($parts['port']))
           ? $parts['port'] : (($scheme === 'https') ? '443' : '80');
 $host = (isset($parts['host'])) ? strtolower($parts['host']) : '';
 $path = (isset($parts['path'])) ? $parts['path'] : '';
 if (($scheme === 'https' && $port != '443')
     || ($scheme === 'http' && $port != '80')) {
     $host = "$host:$port";
 }
 $uri = "$scheme://$host$path";
 
 // params
 if (array_key_exists('oauth_signature', $parameter)) {
   unset($parameter['oauth_signature']);
 }
 
 if (empty($parameter)) return NULL;
 // URLエンコード時、RFC3986を使用するためrawurlencodeを用いる
 $keys  = array_map('rawurlencode', array_keys($parameter));
 $values = array_map('rawurlencode', array_values($parameter));
 $parameter = array_combine($keys, $values);
 uksort($parameter, 'strcmp');
 $pairs = array();
 foreach ($parameter as $key => $value) {
   if (is_array($value)) {
     sort($value, SORT_STRING);
     foreach ($value as $duplicate_value) {
       $pairs[] = $key . '=' . $duplicate_value;
     }
   } else {
     $pairs[] = $key . '=' . $value;
   }
 }
 $params = implode('&', $pairs);
 
 // base_string
 $parts = array($http_method, $uri, $params);
 // URLエンコード時、RFC3986を使用するためrawurlencodeを用いる
 $parts = array_map('rawurlencode', $parts);
 $base_string = implode('&', $parts);
 
 // 2-leggedではtokenは使わないのでそのまま&を結合
 $key = $secret . '&';
 $signature = base64_encode(hash_hmac('sha1', $base_string, $key, true));
 return ($signature === FALSE) ? NULL : $signature;
}