I have a cURL that works well:
curl -H "Authorization: Token 71e24088d13304cc11f5a0fa93f2a2356fc43f41" -H "Content-Type: application/json" -X POST -d
'{
"reviewer": {"name": "test name", "email": "test#email.com"},
"publication": {"title": "test title", "doi": "xxx"},
"complete_date": {"month": 6, "year": 2015}
}'
https://my.url.com/ --insecure
And would like to use the multi curl from Symfony2 Guzzle
What I tried so far:
$client = new \Guzzle\Http\Client();
$request = $client->post('https://my.url.com/');
$jsonBody = "'{ ";
$jsonBody .= '"reviewer": {"name": "'.$review['name'].'", "email":"'.$review['email'].'"}, ';
$jsonBody .= '"publication": {"title": "';
if ($review['article_title'] != '')
$jsonBody .= $review['article_title'];
else
$toExec .= $review['manuscript_title'];
if ($review['doi'] != '')
$jsonBody .= '", "doi": "'.$review['doi'].'"}, ';
else
$toExec .= '"}, ';
$jsonBody .= '"complete_date": {"month": '.$month.', "year": '.$year.'}';
$jsonBody .= "}' ";
$options = [
'headers' => [ 'Content-Type' => 'application/json', 'Authorization' => 'Token 71e24088d13304cc11f5a0fa93f2a2356fc43f41' ],
'body' => $jsonBody,
];
$request->getCurlOptions()->set(CURLOPT_SSL_VERIFYHOST, false);
$request->getCurlOptions()->set(CURLOPT_SSL_VERIFYPEER, false);
$response = $client->post('-d', $options);
But this doesn't work, I am getting an array as a result which I am not supposed to.
You might try moving your authorization to cURL.
$token = '71e24088d13304cc11f5a0fa93f2a2356fc43f41';
$request->getCurlOptions()->set(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$request->getCurlOptions()->set(CURLOPT_USERPWD, "$token:X");
X is the password but often there is none needed so you just add an X (random character)
Related
I am trying to authorize eBay user for exchanging token. Unfortunately, it's not working and returning 2type of error for different aspect. The errors are: 'invalid grant' and 'invalid client'
My code response is 200. But, in postman, it's showing the following response for 2 different Authorization criteria
Error for .. Authorization: Basic 'my code'
{
"error": "invalid_grant",
"error_description": "the provided authorization grant code is invalid or was issued to another client"
}
Error for .. Authorization: Bearer'my code'
{
"error": "invalid_client",
"error_description": "client authentication failed"
}
My Code:
<?php
$clientID = 'client_id';
$clientSecret = 'client_secret';
$authCode = 'authorization_code';
$url = 'https://api.sandbox.ebay.com/identity/v1/oauth2/token';
$redirectUrlName = 'redirect_uri';
$body = http_build_query([
'grant_type' => 'authorization_code',
'code' => $authCode,
'redirect_uri'=> $redirectUrlName
]);
$headers = [
'Cache-Control: no-cache',
'Accept : application/json',
'Content-Type : application/x-www-form-urlencoded',
'Authorization: Basic '.base64_encode($clientID.':'.$clientSecret)
];
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
// CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => $headers
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response."\n";
}
?>
Same thing worked for me, when I was trying for client credentials.
The body section seems to be incorrectly being passed:
'grant_type' => 'authorization_code'&,
'code' => $authCode&,
'redirect_uri'=> $redirectUrlName
In a working code for my case, here is how the body is passed:
CURLOPT_POSTFIELDS => 'grant_type=authorization_code&code=<code value>&redirect_uri=<uri for my test>',
The code was okay, except 2things.
Authorization code: This will come from eBay as a Response. We need to fetch the code.
$headers will have to write as following:
$headers = [
'Cache-Control: no-cache',
'Accept: application/json',
'Content-Type: application/x-www-form-urlencoded',
'Authorization: Basic '.base64_encode($clientID.':'.$clientSecret)
];
There Will have no space between Cache-Control and Colon(:). That mean, there will have no space at key and colon. Applicable for all key-value pair.
I am following the instructions here:
https://learn.microsoft.com/en-us/graph/auth-v2-user?view=graph-rest-1.0#3-get-a-token
I get the authorisation response and therefore the required code, but when I request the token I get a "HTTP/1.1 401 Unauthorized" response.
This is my code (not for production, just for me to get the flow/code right first):
<?php
/*
Auth
https://learn.microsoft.com/en-us/graph/auth-v2-user?view=graph-rest-1.0
*/
define("HOST", 'https://login.microsoftonline.com');
define("TENANT", 'common');
define("AUTH_ENDPOINT", HOST.'/'.TENANT.'/oauth2/v2.0/authorize');
define("TOKEN_ENDPOINT", HOST.'/'.TENANT.'/oauth2/v2.0/token');
define("CLIENT_ID", '<< FROM AZURE PORTAL >>');
define("CLIENT_SECRET", '<< FROM AZURE PORTAL >>');
define("ALL_SCOPES", rawurlencode('offline_access user.read mail.read'));
define("CALLBACK", rawurlencode('http://localhost:300/graph2/auth.php'));
// Build URL
$url = AUTH_ENDPOINT."?client_id=".CLIENT_ID;
$url .= "&response_type=code";
$url .= "&redirect_uri=".CALLBACK;
$url .= "&response_mode=query";
$url .= "&scope=".ALL_SCOPES;
echo "<a href=$url>$url</a>";
if (isset($_GET))
{
echo '<pre>';print_r($_GET);echo'</pre>';
if (isset($_GET['code']))
{
// Got authorisation code - now need token
$response = requestAccessTokenByVerifier($_GET['code']);
echo ">".$response;
}
}
function requestAccessTokenByVerifier($verifier)
{
return requestAccessToken(
array(
'client_id' => CLIENT_ID,
'redirect_uri' => CALLBACK,
'client_secret' => CLIENT_SECRET,
'code' => $verifier,
'grant_type' => 'authorization_code',
'scope' => ALL_SCOPES
)
);
}
function requestAccessToken($content)
{
$response = sendRequest(TOKEN_ENDPOINT, 'POST', $content);
if ($response !== false)
{
$authToken = json_decode($response);
if (!empty($authToken) && !empty($authToken->{ACCESSTOKEN})) return $authToken;
}
die("No access token");
return false;
}
function sendRequest($url, $method = 'GET', $data = array(), $headers = array('Content-Type: application/x-www-form-urlencoded'))
{
$context = stream_context_create(
array(
'http' => array(
'method' => $method,
'header' => $headers,
'content' => buildQueryString($data)
)
)
);
echo "URL: $url<br>";
echo '<pre>';print_r($data);echo '</pre>';
echo buildQueryString($data)."<br>";
$response = file_get_contents($url, false, $context);
echo '<pre>';var_dump($http_response_header);echo '</pre>';
return $response;
}
function buildQueryString($array)
{
$result = '';
foreach ($array as $k => $v)
{
if ($result == '') $prefix = ''; else $prefix = '&';
$result .= $prefix . $k . '=' . $v;
}
return $result;
}
?>
As you will see I've put a few basic diagnostics in there which show I am getting the code required successfully, but then not being able to get a token from the code.
Can anybody suggest what to try next, I wonder either from a debugging point of view or alternative approaches.
Thanks.
OK, after digging around I realised I'd made a stupid mistake, but just in case anybody else does the same - you need to use the client secret value not id!
I've deleted that client secret :)
Hope that helps somebody else bashing their head against a brick wall.
I am attempting to replicate a CURL POST request in Guzzle, but Guzzle request is failing.
This is the CURL request that works successfully:
$file = new \CURLFile( $document );
$file->setPostFilename( basename( $document ) );
$ch = curl_init();
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_URL, $endpoint );
curl_setopt( $ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . $accessToken,
"Content-Type: multipart/form-data",
] );
curl_setopt( $ch, CURLOPT_POSTFIELDS, [ 'fileData' => $file ] );
$response = curl_exec( $ch );
And here is what I am currently using for the Guzzle request but it does not work:
$options['multipart'][] = [
'name' => 'fileData',
'contents' => fopen( $document, 'r' ),
'filename' => basename( $document ),
];
$request = $provider->getAuthenticatedRequest( 'POST', $endpoint, $accessToken, $options );
$response = $provider->getParsedResponse( $request );
The response from the Guzzle request is as follows:
{"message":"File cannot be empty","errors":[{"code":"Missing","fields":["document"]}]}
It's worth noting I am using the thephpleague/oauth2-client library to send the request. I'm looking for any discrepencies between the two request or information on how I can troubleshoot this further myself as I have been spinning my wheels all day on this. Much appreciated
thephpleague/oauth2-client uses different Providers to create the requests and these Providers implement AbstractProvider
The argument $options of AbstractProvider 's getAuthenticatedRequest() is different from GuzzleHttp\Client 's request():
/**
* Returns an authenticated PSR-7 request instance.
...
* #param array $options Any of "headers", "body", and "protocolVersion".
* #return RequestInterface
*/
public function getAuthenticatedRequest($method, $url, $token, array $options = [])
Only keys allowed for $options are "headers", "body", and "protocolVersion".
You should do the extra effort and create the headers and body needed:
$file = new \CURLFile( $document );
$file->setPostFilename( basename( $document ) );
$data = array(
'uploaded_file' => $file
);
$options = array(
'headers' => array("Content-Type" => "multipart/form-data"),
'body' => $data
);
$request = $provider->getAuthenticatedRequest( 'POST', $endpoint, $accessToken, $options );
Reference
Send file via cURL from form POST in PHP
Hel-lo! Need to retrieve GWT data (top pages, top queries, internal/external links, etc.). Wrote a php-script (based on this):
//"GetAccessCode.php" file
$OAuth = array(
'oauth_uri' => 'https://accounts.google.com/o/oauth2/auth',
'client_id' => 'here is my client id',
'client_secret' => 'here is my client secret',
'redirect_uri' => 'http://localhost/google/GetAccessCode.php',
'oauth_token_uri' => 'https://accounts.google.com/o/oauth2/token',
);
$token = array(
'access_token' => '',
'token_type' => '',
'expires_in' => '',
'refresh_token' => ''
);
$title = 'No Code';
$AuthCode = 'Null';
// see if error parameter exisits
$error = _get_url_param($_SERVER['REQUEST_URI'], 'error');
if ($error != NULL)
{ // this means the user denied api access to GWMTs
$title = $error;
}
else
{ // does the code parameter exist?
$AuthCode = _get_url_param($_SERVER['REQUEST_URI'], 'code');
if ($AuthCode == NULL)
{ // get authorization code
$OAuth_request = _formatOAuthReq($OAuth, "https://www.google.com/webmasters/tools/feeds/sites/"); //**WHAT URI NEED TO BE HERE?**
header('Location: ' . $OAuth_request);
exit; // the redirect will come back to this page and $code will have a value
}
else
{
$title = 'Got Authorization Code';
// now exchange Authorization code for access token and refresh token
$token_response = _get_auth_token($OAuth, $AuthCode);
$json_obj = json_decode($token_response);
$token['access_token'] = $json_obj->access_token;
$token['token_type'] = $json_obj->token_type;
$token['expires_in'] = $json_obj->expires_in;
$token['refresh_token'] = $json_obj->refresh_token;
$sites = _get_wmt_sites_feed($token);
echo $sites;
}
}
// Return the list of sites registered in your Google Webmaster Tools
function _get_wmt_sites_feed($access_tokens)
{
$post_string = "https://www.google.com/webmasters/tools/feeds/sites/"; //**WHAT URI NEED TO BE HERE?**
$post_string .= '?v=2';
$post_string .= '&oauth_token=' . $access_tokens['access_token'];
$response = file_get_contents($post_string);
return _parse_wmt_sites_response($response);
}
function _parse_wmt_sites_response($response)
{
$xml = simplexml_load_string($response);
$response = '<br />';
foreach ($xml->entry as $entry)
{
foreach ($entry->title as $title)
{
$response .= "<p>$title</p>";
}
}
return $response;
}
function _get_auth_token($params, $code)
{
$url = $params['oauth_token_uri'];
$fields = array(
'code' => $code,
'client_id' => $params['client_id'],
'client_secret' => $params['client_secret'],
'redirect_uri' => $params['redirect_uri'],
'grant_type' => 'authorization_code'
);
$response = _do_post($url, $fields);
return $response;
}
function _do_post($url, $fields)
{
$fields_string = '';
foreach ($fields as $key => $value)
{
$fields_string .= $key . '=' . $value . '&';
}
$fields_string = rtrim($fields_string, '&');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
function _formatOAuthReq($OAuthParams, $scope)
{
$uri = $OAuthParams['oauth_uri'];
$uri .= "?client_id=" . $OAuthParams['client_id'];
$uri .= "&redirect_uri=" . $OAuthParams['redirect_uri'];
$uri .= "&scope=" . $scope;
$uri .= "&response_type=code";
return $uri;
}
function _get_url_param($url, $name)
{
parse_str(parse_url($url, PHP_URL_QUERY), $params);
return isset($params[$name]) ? $params[$name] : null;
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><?= $title; ?></title>
</head>
<body>
<h1>OAuth2 Authorization Code</h1>
<p>Authorization Code: <?= $AuthCode; ?></p>
<p>access token: <?=$token['access_token'];?></p>
<p>expires in: <?=$token['expires_in'];?></p>
<p>refresh token: <?=$token['refresh_token'];?></p>
<p></p>
</body>
</html>
What URI need I to write in the code above instead of https:// www.google.com/webmasters/tools/feeds/sites/ to retrieve the desired data? In this nice code - https://github.com/eyecatchup/php-webmaster-tools-downloads - author uses https:// www.google.com/webmasters/tools/downloads-list?hl=en&siteUrl=http: //site.com/, but also he uses ClientLogin. I try to use this link in my script, but it generates mistakes, because, as I understand, this is not a right scope. So, what is right?
Also found this post here, it mentions about some Basic Authentication. I'm a beginner in Google API, please, tell, what do they mean?
Anyone know how I can tweak the settings in the Wordpress theme used in this site (http://www.ethnecity.church.ly/) to make the Twitter section (near the bottom left of the page) show the tweets for the account instead of the timeline from the Twitter account? Note: the plugin is using OAuth...I just don't know how to tell it to display tweets instead of the timeline.
I believe this is the code that displays the twitter info:
<?php
$user_screen_name = 'ethnecity';
$user_full_name = '(removed)';
$settings = array(
'consumer_key' => '(removed)',
'consumer_secret' => '(removed)',
'access_token' => '(removed)',
'access_token_secret' => '(removed)');
$api_url = 'https://api.twitter.com/1.1/statuses/home_timeline.json';
$api_params = array(
'count' => 40,
'contributor_details' => 'false',
'include_entities' => 'false');
// OAuth:
function oauth_encode($data){
if(is_array($data)){
return array_map('oauth_encode', $data);
} else if(is_scalar($data)) {
return str_ireplace(array('+', '%7E'), array(' ', '~'), rawurlencode($data));
} else {
return '';
}}
// OAuth base settings
$oauth_params = array(
'oauth_consumer_key' => $settings['consumer_key'],
'oauth_nonce' => md5(microtime() . mt_rand()),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_timestamp' => time(),
'oauth_token' => $settings['access_token'],
'oauth_version' => '1.0',
);
// Sign OAuth params
$sign_params = array_merge($oauth_params, $api_params);
uksort($sign_params, 'strcmp');
foreach ($sign_params as $k => $v) {
$sparam[] = oauth_encode($k) . '=' . oauth_encode($v);
}
$sparams = implode('&', $sparam);
$base_string = 'GET&' . oauth_encode($api_url) . '&' . oauth_encode($sparams);
$signing_key = oauth_encode($settings['consumer_secret']) . '&' . oauth_encode($settings['access_token_secret']);
$oauth_params['oauth_signature'] = oauth_encode(base64_encode(hash_hmac('sha1', $base_string, $signing_key, TRUE)));
// Set Authorization header:
uksort($oauth_params, 'strcmp');
foreach ($oauth_params as $k => $v) {
$hparam[] = $k . '="' . $v . '"';
}
$hparams = implode(', ', $hparam);
$headers = array();
$headers['Expect'] = '';
$headers['Authorization'] = 'OAuth ' . $hparams;
foreach ($headers as $k => $v) {
$curlheaders[] = trim($k . ': ' . $v);
}
// Format params:
foreach ($api_params as $k => $v) {
$rparam[] = $k . '=' . $v;
}
$rparams = implode('&', $rparam);
// echo "curl --get '" . $api_url . "' --data '" . $rparams . "' --header 'Authorization: OAuth " . $hparams . "' --verbose" . PHP_EOL;
// GET:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_url . '?' . $rparams);
curl_setopt($ch, CURLOPT_HTTPHEADER, $curlheaders);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10 );
$response = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$info = curl_getinfo($ch);
$error = curl_error($ch);
$errno = curl_errno($ch);
curl_close($ch);
function get_twitterfeeds(){
global $code; global $response;
if($code != 200){
//echo 'Error' . PHP_EOL;
//echo $code . PHP_EOL;
//print_r($response);
//print_r($info);
} else {
$all = json_decode($response, true);
//echo '<pre />';
// print_r($all);
//exit;
return $all;
}
}
?>
Your code should be modified so as to retrieve user's timeline. As per the current code it should return only tweets present on your timeline.
If you need only your's or a particular user's feed , your code should be modified in such a way that resource URL should be changed.
$api_url = 'https://api.twitter.com/1.1/statuses/user_timeline.json';
$api_params = array(
'screen_name' => 'ethnecity'
'count' => 40,
'contributor_details' => 'false',
'include_entities' => 'false'
);
Please verify the document https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline