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

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

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

/**
 * OAuth HMAC-SHA1方式の署名を作成する.
 *
 * @link https://support.e-map.ne.jp/manuals/v3/?q=sig_implement
 *
 * @param string http_method   HTTPメソッドを指定
 * @param array  parameter   クエリパラメータとOAuthパラメータをマージしたもの
 * @param string uri   実際にリクエストするURI(リクエストパラメータは含めない)
 * @param string secret   秘密鍵
 * @param string signature_method   ハッシュアルゴリズム
 *
 * @return string 作成した署名。作成失敗した場合はNULL
 */
function make_signature_hmac($http_method, $parameter, $uri, $secret, $signature_method)
{
  // 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 . '&';
  $hmac_algo = strtolower(str_replace('HMAC-', '', $signature_method));
  $signature = base64_encode(hash_hmac($hmac_algo, $base_string, $key, true));
  return ($signature === FALSE) ? NULL : $signature;
}