old attempt to add oauth1 support (twitter...)

oauth1test
Vitaliy Filippov 2015-06-06 18:43:41 +03:00
parent b789b77c07
commit bb343f4491
2 changed files with 234 additions and 24 deletions

View File

@ -5,6 +5,7 @@ namespace OAuth2;
class AccessToken
{
public $accessToken;
public $tokenSecret; /* OAuth 1.0 token secret */
public $expires;
public $refreshToken;
public $uid;
@ -17,40 +18,53 @@ class AccessToken
*/
public function __construct(array $options = null)
{
if (!isset($options['access_token']))
if (isset($options['access_token']))
{
// OAuth 2.0
$this->accessToken = $options['access_token'];
if (!empty($options['refresh_token']))
{
$this->refreshToken = $options['refresh_token'];
}
// We need to know when the token expires. Show preference to
// 'expires_in' since it is defined in RFC6749 Section 5.1.
// Defer to 'expires' if it is provided instead.
if (!empty($options['expires_in']))
{
$this->expires = time() + ((int) $options['expires_in']);
}
elseif (!empty($options['expires']))
{
// Some providers supply the seconds until expiration rather than
// the exact timestamp. Take a best guess at which we received.
$expires = $options['expires'];
$expiresInFuture = $expires > time();
$this->expires = $expiresInFuture ? $expires : time() + ((int) $expires);
}
}
elseif (isset($options['oauth_token']))
{
// OAuth 1.0
$this->accessToken = $options['oauth_token'];
if (!empty($options['oauth_token_secret']))
{
$this->tokenSecret = $options['oauth_token_secret'];
}
}
else
{
throw new \InvalidArgumentException(
'Required option not passed: access_token in '.print_r($options, true)
'Required option not passed: access_token or oauth_token in '.print_r($options, true)
);
}
$this->accessToken = $options['access_token'];
if (!empty($options['uid']))
{
$this->uid = $options['uid'];
}
if (!empty($options['refresh_token']))
{
$this->refreshToken = $options['refresh_token'];
}
// We need to know when the token expires. Show preference to
// 'expires_in' since it is defined in RFC6749 Section 5.1.
// Defer to 'expires' if it is provided instead.
if (!empty($options['expires_in']))
{
$this->expires = time() + ((int) $options['expires_in']);
}
elseif (!empty($options['expires']))
{
// Some providers supply the seconds until expiration rather than
// the exact timestamp. Take a best guess at which we received.
$expires = $options['expires'];
$expiresInFuture = $expires > time();
$this->expires = $expiresInFuture ? $expires : time() + ((int) $expires);
}
}
/**

196
src/OAuth1Provider.php Normal file
View File

@ -0,0 +1,196 @@
<?php
namespace OAuth2;
class OAuth1Provider extends AbstractProvider
{
public $siteUrl = '';
public $authorizeUrl = '';
public $requestTokenUrl = '';
public $accessTokenUrl = '';
public $callbackUrl = '';
public $consumerKey = '';
public $consumerSecret = '';
public $clientId = '';
public $clientSecret = '';
public $redirectUri = '';
public $state;
public $name;
public $uidKey = 'uid';
public $method = 'post';
public $responseType = 'string';
public $headers = [];
public $authorizationHeader;
protected $redirectHandler;
public function __construct($options = [])
{
foreach ($options as $option => $value)
{
if (property_exists($this, $option))
{
$this->{$option} = $value;
}
}
}
/**
* Get the URL that this provider users to request an unauthenticated "request token"
* which may then be exchanged for an access token.
*
* This URL MUST be in normalized form (lowercase, no query parameters, port excluded
* ONLY if equal to standard http 80 or https 443).
*
* @return string
*/
abstract public function urlRequestToken();
protected function nonce()
{
$max = 1+mt_getrandmax();
$bits = 0;
while ($max)
{
$max = $max >> 1;
$bits++;
}
$r = '';
for ($i = 0; $i < 256; $i += $bits)
{
$r .= pack('L', mt_rand());
}
}
protected function sign($post, $url, &$params, $token = NULL)
{
$params = [
'oauth_consumer_key' => $this->consumerKey,
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_timestamp' => time(),
'oauth_nonce' => base64_encode(pack('LLLL', mt_rand(), mt_rand(), mt_rand(), mt_rand())),
] + $params;
ksort($params);
$baseStr = ($post ? 'POST' : 'GET').'&'.rawurlencode($url).
'&'.rawurlencode(http_build_query($params, '', '&', PHP_QUERY_RFC3986));
$key = rawurlencode($this->consumerSecret).'&'.($token ? rawurlencode($token->tokenSecret) : ''));
$params['oauth_signature'] = hash_hmac('sha1', $baseStr, $key, true);
}
protected function request($url, $params, $token)
{
$this->sign($this->method == 'POST', $url, $params, $token);
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
// No providers included with this library use GET but 3rd parties may
CURLOPT_POST => $this->method == 'POST',
CURLOPT_HTTPHEADER => $this->getHeaders($params),
CURLOPT_HEADER => true,
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($curl);
curl_close($curl);
$response = explode("\r\n\r\n", $response, 2);
$header = explode("\r\n", $response[0]);
$status = explode(" ", $header[0], 3);
if ($status[1] != 200)
{
throw new \Exception($header[0]);
}
$response = $response[1];
switch ($this->responseType)
{
case 'json':
$result = json_decode($response, true);
if (JSON_ERROR_NONE !== json_last_error())
{
$result = [];
}
break;
case 'string':
$result = [];
parse_str($response, $result);
break;
}
return $result;
}
public function getAuthorizationUrl($options = [])
{
$result = $this->request($this->urlRequestToken(), []);
$this->state = [ 'request_token' => $result ];
$params = [
'oauth_callback' => $this->redirectUri,
'oauth_token' => $this->state['request_token']['oauth_token'],
];
return $this->urlAuthorize().'?'.http_build_query($params);
}
public function authorize($options = [])
{
$url = $this->getAuthorizationUrl($options);
if ($this->redirectHandler)
{
$handler = $this->redirectHandler;
return $handler($url);
}
header('Location: ' . $url);
exit;
}
public function getAccessToken($grant = 'authorization_code', $params = [])
{
$result = $this->request($this->urlAccessToken(), [
'oauth_token' => $this->state['request_token'],
]);
$result = $this->prepareAccessTokenResult($result);
return new AccessToken($result);
}
public function getUserDetails(AccessToken $token)
{
$response = $this->fetchUserDetails($token);
return $this->userDetails(json_decode($response), $token);
}
protected function fetchUserDetails(AccessToken $token)
{
$url = $this->urlUserDetails($token);
$headers = $this->getHeaders($token);
return $this->fetchProviderData($url, $headers);
}
protected function fetchProviderData($url, array $headers = [])
{
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($status != 200)
{
throw new \Exception($response);
}
return $response;
}
public function getAuthorizationHeaders($params)
{
foreach ($params as $k => &$v)
{
$v = $k.'="'.rawurlencode($v).'"';
}
return [ 'Authorization: OAuth '.implode(', ', $params) ];
}
}