OAuthSignature.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. <?php
  2. if ( !class_exists('Puc_v4p11_OAuthSignature', false) ):
  3. /**
  4. * A basic signature generator for zero-legged OAuth 1.0.
  5. */
  6. class Puc_v4p11_OAuthSignature {
  7. private $consumerKey = '';
  8. private $consumerSecret = '';
  9. public function __construct($consumerKey, $consumerSecret) {
  10. $this->consumerKey = $consumerKey;
  11. $this->consumerSecret = $consumerSecret;
  12. }
  13. /**
  14. * Sign a URL using OAuth 1.0.
  15. *
  16. * @param string $url The URL to be signed. It may contain query parameters.
  17. * @param string $method HTTP method such as "GET", "POST" and so on.
  18. * @return string The signed URL.
  19. */
  20. public function sign($url, $method = 'GET') {
  21. $parameters = array();
  22. //Parse query parameters.
  23. $query = parse_url($url, PHP_URL_QUERY);
  24. if ( !empty($query) ) {
  25. parse_str($query, $parsedParams);
  26. if ( is_array($parameters) ) {
  27. $parameters = $parsedParams;
  28. }
  29. //Remove the query string from the URL. We'll replace it later.
  30. $url = substr($url, 0, strpos($url, '?'));
  31. }
  32. $parameters = array_merge(
  33. $parameters,
  34. array(
  35. 'oauth_consumer_key' => $this->consumerKey,
  36. 'oauth_nonce' => $this->nonce(),
  37. 'oauth_signature_method' => 'HMAC-SHA1',
  38. 'oauth_timestamp' => time(),
  39. 'oauth_version' => '1.0',
  40. )
  41. );
  42. unset($parameters['oauth_signature']);
  43. //Parameters must be sorted alphabetically before signing.
  44. ksort($parameters);
  45. //The most complicated part of the request - generating the signature.
  46. //The string to sign contains the HTTP method, the URL path, and all of
  47. //our query parameters. Everything is URL encoded. Then we concatenate
  48. //them with ampersands into a single string to hash.
  49. $encodedVerb = urlencode($method);
  50. $encodedUrl = urlencode($url);
  51. $encodedParams = urlencode(http_build_query($parameters, '', '&'));
  52. $stringToSign = $encodedVerb . '&' . $encodedUrl . '&' . $encodedParams;
  53. //Since we only have one OAuth token (the consumer secret) we only have
  54. //to use it as our HMAC key. However, we still have to append an & to it
  55. //as if we were using it with additional tokens.
  56. $secret = urlencode($this->consumerSecret) . '&';
  57. //The signature is a hash of the consumer key and the base string. Note
  58. //that we have to get the raw output from hash_hmac and base64 encode
  59. //the binary data result.
  60. $parameters['oauth_signature'] = base64_encode(hash_hmac('sha1', $stringToSign, $secret, true));
  61. return ($url . '?' . http_build_query($parameters));
  62. }
  63. /**
  64. * Generate a random nonce.
  65. *
  66. * @return string
  67. */
  68. private function nonce() {
  69. $mt = microtime();
  70. $rand = null;
  71. if ( is_callable('random_bytes') ) {
  72. try {
  73. $rand = random_bytes(16);
  74. } catch (Exception $ex) {
  75. //Fall back to mt_rand (below).
  76. }
  77. }
  78. if ( $rand === null ) {
  79. $rand = mt_rand();
  80. }
  81. return md5($mt . '_' . $rand);
  82. }
  83. }
  84. endif;