OAUTH 1.0a

The difference between versions 2.0 and 1.0 is the complex system of signatures, in version 2.0, the signature system has been removed by the authentication via SSL / TSL. One of the hardest parts of working with OAuth 1 is signing requests. It's important to understand the process from the start.

Request signing in OAuth is a key part of ensuring your application can't be spoofed. This uses a pre-established shared secret only known by the server and the client, which is a key reason why you should keep your credentials secret. This secret is then mixed with the request data and a nonce to ensure the signature can't be used multiple times. oauth_signature is created by basestring and Signature Key.

More details about oauth 1.0

<?php

/*
* This file build on OAUTH 1.0a
*/

class oauthhelper {

public static function request($config, $endpoint, $access_token, $method = 'GET', $extend_params = null) {
$params = self::get_request_info_params($config, $access_token);
$oauth_sig = self::build_oauth_sig($params, $method, $endpoint, $config, $access_token['oauth_token_secret']);
$header = self::build_authen_header($config, $params, $oauth_sig, $extend_params, $endpoint, $method);
$data = self::make_request($endpoint, $header, null, $method);

return ($data);
}

/**
*
* @param array $config
* @param string $endpoint
* @param array $access_token
* @param tring $method
* @return array
*/
public static function get_info($config, $endpoint, $access_token, $method = 'GET', $extend_params = null) {
$params = self::get_request_info_params($config, $access_token);
$oauth_sig = self::build_oauth_sig($params, $method, $endpoint, $config, $access_token['oauth_token_secret']);
$header = self::build_authen_header($config, $params, $oauth_sig, $extend_params, $endpoint, $method);
$data = self::make_request($endpoint, $header, null, $method);

return ($data);
}

/**
*
* @param array $config
* @param string $method
* @param string $endpoint
* @param array $temp_token
* @param string $oauth_verifier
* @return array
*/
public static function get_access_token($config, $method, $endpoint, $temp_token, $oauth_verifier) {
$params = self::get_access_token_params($config, $temp_token, $oauth_verifier);
$oauth_sig = self::build_oauth_sig($params, $method, $endpoint, $config, $temp_token['oauth_token_secret']);
$header = self::build_authen_header($config, $params, $oauth_sig, null, $endpoint, $method);

$data = self::make_request($endpoint, $header, null, $method);

return $data;
}

/**
*
* @param array $config
* @param string $method
* @param string $endpoint
* @return array
*/
public static function get_request_token($config, $method, $endpoint) {
$params = self::get_request_token_params($config);
$oauth_sig = self::build_oauth_sig($params, $method, $endpoint, $config);
$header = self::build_authen_header($config, $params, $oauth_sig, null, $endpoint, $method);
var_dump($header);

$data = self::make_request($endpoint, $header, null, $method);
return $data;
}

/**
*
* @param array $params
* @param string $oauth_sig
* @return string
*/
public static function build_authen_header($config, $params, $oauth_sig, $extend_params = null, $endpoint = null, $method = null) {
if ($extend_params != null) {
foreach ($extend_params as $key => $value) {
$params[$key] = $value;
}
}
$ret = array();

$params['oauth_signature'] = $oauth_sig;

ksort($params);

foreach ($params as $parameter => $value) {
$pairs[] = $parameter . '="' . rawurlencode($value) . '"';
}
$params_data = implode(', ', $pairs);

if ($endpoint != null) {
$path_data = self::get_url_info($endpoint);
if (isset($config['url_parameters']) && $config['url_parameters'] == true) {
// var_dump($params_data);
$raw = str_replace('"', '', $params_data);
// var_dump($raw);
$raw = str_replace(', ', '&', $raw);
// var_dump($raw);
$url_params = $path_data['path'] . '?' . $raw . ' HTTP/1.1';
} else {
$url_params = $path_data['path'];
}
$ret[] = $method . ' ' . $url_params;
$ret[] = 'Host: ' . $path_data['host'];
}

$ret[] = 'Accept: */*';
if (isset($config['authorization_header']) && $config['authorization_header'] == false) {

} else {
$authen = 'Authorization: OAuth ' . $params_data;
$ret[] = $authen;
}


$ret[] = 'Expect:';
return $ret;
// return ['Accept: application/json', $authen, 'Expect:'];
}

/**
* get params array for calling request token
* @param array $config
* @return array
*/
private static function get_request_token_params($config) {
$params = array(
'oauth_version' => '1.0',
'oauth_nonce' => self::generateNonce(),
'oauth_timestamp' => time(),
'oauth_consumer_key' => $config['client_id'],
'oauth_callback' => $config['redirect_uri'],
'oauth_signature_method' => 'HMAC-SHA1',
);
return $params;
}

/**
* get params array when calling access token
* @param array $config
* @param array $temp_token
* @param string $oauth_verifier
* @return array
*/
private static function get_access_token_params($config, $temp_token, $oauth_verifier) {
$params = array(
'oauth_version' => '1.0',
'oauth_nonce' => self::generateNonce(),
'oauth_timestamp' => time(),
'oauth_consumer_key' => $config['client_id'],
'oauth_token' => $temp_token['oauth_token'],
'oauth_verifier' => $oauth_verifier,
'oauth_signature_method' => 'HMAC-SHA1',
);

return $params;
}

/**
* get params array when calling request user'd details
* @param array $config
* @param array $access_token
* @return array
*/
private static function get_request_info_params($config, $access_token) {
$params = array(
'oauth_version' => '1.0',
'oauth_nonce' => self::generateNonce(),
'oauth_timestamp' => time(),
'oauth_consumer_key' => $config['client_id'],
'oauth_token' => $access_token['oauth_token'],
'oauth_signature_method' => 'HMAC-SHA1',
);

return $params;
}

/**
*
* @param array $params
* @param string $method
* @param string $endpoint
* @param array $config
* @param string $token_secret
* @return array
*/
private static function build_oauth_sig($params, $method, $endpoint, $config, $token_secret = '') {
$base_string = self::create_base_string($params, $method, $endpoint);
$key = self::create_key($config, $token_secret);
var_dump($key);
var_dump($base_string);
$ret = base64_encode(hash_hmac('sha1', $base_string, $key, true));
var_dump($ret);
return $ret;
}

private static function create_base_string($params, $method, $endpoint) {
uksort($params, 'strcmp');
foreach ($params as $parameter => $value) {
$pairs[] = $parameter . '=' . rawurlencode($value);
}

$params_data = (implode('&', $pairs));
$base_array = [
strtoupper($method),
$endpoint,
$params_data
];
$base_encode = array();
foreach ($base_array as $base) {
$base_encode[] = rawurlencode($base);
}

$base_string = implode('&', $base_encode);
return $base_string;
}

private static function create_key($config, $token_secret = '') {
$parts = [rawurlencode($config['client_secret']), rawurlencode($token_secret)];
$key = implode('&', $parts);
return $key;
}

/**
* return randon string
* @return string
*/
public static function generateNonce() {
return md5(microtime() . mt_rand());
}

/**
* make request data
* @param string $endpoint
* @param array $header
* @param string $post_fields
* @return string
*/
public static function make_request($endpoint, $header = null, $post_fields = null, $method = null) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);

curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
switch ($method) {
case 'GET':
break;
case 'POST':
break;
default :
break;
}
if ($header != null) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
}
if ($post_fields != null) {
// curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
}
$data = curl_exec($ch);

if (curl_errno($ch) > 0) {
return parse_string_to_array(curl_error($ch));
}

curl_close($ch);
return self::parse_string_to_array($data);
}

/**
* parse string to array
* @param string $input
* @return array
*/
private static function parse_string_to_array($input) {

if ($input == null && $input == '') {
return '';
} else if ($input != strip_tags($input)) {
// contains HTML
return $input;
} else if (json_decode($input) != null) {
return json_decode($input);
} else if (strpos($input, '&') != false) {
$ret = array();
$value_array = explode('&', $input);
if (count($value_array)) {
foreach ($value_array as $data) {
$key_data = explode('=', $data);
if (count($key_data) > 0) {
$ret[$key_data[0]] = $key_data[1];
}
}
}

return $ret;
} else {
return $input;
}
}

private static function get_url_info($endpoint) {
return (parse_url($endpoint));
}

}

Basestring

The base string uses three pieces of data: the HTTP method (GET, POST, etc), the URL (without GET parameters), and any passed parameters. These follow a very specific set of rules, which loosely summarised are:
Method: Uppercase HTTP method.
URL: Lowercase scheme and host
Request Parameters: OAuth parameters from Authorization header (excluding oauth_signature itself), Combine key and value with "=", then concatenate with & into a string.
These pieces are then combined by URL-encoding each, then concatenating with & into a single string.

In this example, we send request request_token to twitter api, request header would be

  • GET /oauth/request_token
    Host: api.twitter.com
    Authorization: OAuth
    oauth_version=1.0
    ,oauth_nonce=c3039d394eb1dba5f5a1cf66054c9446
    ,oauth_timestamp=1482889079
    ,oauth_consumer_key=NAnmPHh8ocjHM47izMLzKzNb
    ,oauth_callback=http://yourdomain.com/callback
    ,oauth_signature_method=HMAC-SHA1
    ,oauth_signature='oauth_signature'

Follow example

  • $Method = GET
    $URL = https://api.twitter.com/oauth/request_token
    $Request_Parameter:oauth_version=1.0&oauth_nonce=nonce&oauth_timestamp=1413212144&oauth_consumer_key=client_id&oauth_callback=http://yourdomain.com&oauth_signature_method=HMAC-SHA1

$URL should be urlencode

  • $URL = rawurlencode($URL);
  • In this example $URL = https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token

$Request_Parameter need to be sorted in alphabetical order and should be urlencode

  • $Request_Parameter = rawurlencode($Request_Parameter);
  • In this example $Request_Parameter = oauth_callback%3Dhttp%253A%252F%252Flogin-tutorials.com%252Ftwitter-callback.php%26oauth_consumer_key%3DNAnmPHh8ocjHM47izMLzKzND%26oauth_nonce%3Dc3039d394eb1dba5f5a1cf66054c9446%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1482889079%26oauth_version%3D1.0

And $basestring is

  • $basestring = GET&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_version=1.0&oauth_callback%3Dhttp%253A%252F%252Flogin-tutorials.com%252Ftwitter-callback.php%26oauth_consumer_key%3DNAnmPHh8ocjHM47izMLzKzND%26oauth_nonce%3Dc3039d394eb1dba5f5a1cf66054c9446%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1482889079%26oauth_version%3D1.0

Signature Key

The signature key for HMAC-SHA1 is created by taking the client/consumer secret and the token secret, URL-encoding each, then concatenating them with & into a string.

For example:

  • $client_secret = iYry1a722aipQZnQXaMG6eAPQ9JZDWhRPmmouiUXtBLU;
    $token_secret= '';

    $key = $client_secret. '&'.$token_secret
  • $key = iYry1a722aipQZnQXaMG6eAPQ9JZDWhRPmmouiUXtBLU&

Once you have the $key and $basestring, signature is created as follows

  • $oauth_signature = base64_encode(hash_hmac('sha1',$basestring,$key));
  • In this example $oauth_signature = bPqTXDkwyCtEmcCzw4yTObPxXQ4=

Request header would be

  • GET /oauth/request_token
    Host: api.twitter.com
    Authorization: OAuth
    oauth_version=1.0
    ,oauth_nonce=c3039d394eb1dba5f5a1cf66054c9446
    ,oauth_timestamp=1482889079
    ,oauth_consumer_key=NAnmPHh8ocjHM47izMLzKzNb
    ,oauth_callback=http://yourdomain.com/callback
    ,oauth_signature_method=HMAC-SHA1
    ,oauth_signature=bPqTXDkwyCtEmcCzw4yTObPxXQ4

This is the most basic things about OAuth 1.0, if you have any questions, do not hesitate to ask, or view twitter login that using oauth 1.0a