got a 401 when I get access token for LinkedIn - php

$oauth->getAccessToken() causes Invalid auth/bad request (got a 401, expected HTTP/1.1 20X or a redirect).
How do I look at the request headers to figure out what exactly is wrong?
$oauth = new OAuth(CONSUMER_KEY, CONSUMER_SECRET);
$oauth->disableSSLChecks();
$request_token_response = $oauth->getRequestToken('https://api.linkedin.com/uas/oauth/requestToken');
if($request_token_response === FALSE) {
throw new Exception("Failed fetching request token, response was: " . $oauth->getLastResponse());
} else {
$request_token = $request_token_response;
var_dump($request_token);
if (!isset($_GET['oauth_verifier'])) {
$this->redirect("https://api.linkedin.com/uas/oauth/authorize?oauth_token=" . $request_token['oauth_token']);
} else {
$oauth_verifier = $_GET['oauth_verifier'];
$oauth->setToken($request_token['oauth_token'], $request_token['oauth_token_secret']);
$access_token_url = 'https://api.linkedin.com/uas/oauth/accessToken';
$access_token_response = $oauth->getAccessToken($access_token_url, "", $oauth_verifier);
if($access_token_response === FALSE) {
throw new Exception("Failed fetching request token, response was: " . $oauth->getLastResponse());
} else {
$access_token = $access_token_response;
$params = array();
$headers = array();
$method = OAUTH_HTTP_METHOD_GET;
// Specify LinkedIn API endpoint to retrieve your own profile
$url = "http://api.linkedin.com/v1/people/~";
// By default, the LinkedIn API responses are in XML format. If you prefer JSON, simply specify the format in your call
// $url = "http://api.linkedin.com/v1/people/~?format=json";
// Make call to LinkedIn to retrieve your own profile
$oauth->fetch($url, $params, $method, $headers);
echo $oauth->getLastResponse();
}
}
}
}

oauth_verifier only verifies the request_token from which it was obtained. I needed to store the original request_token in session instead of getting a new request_token on callback.

Related

hotelbed API http error

Here below i have attached my api request
$apiKey = "XXXX";
$Secret = "XXX";
$endpoint = "https://api.test.hotelbeds.com/hotel-api/1.0/hotels";
$request = new http\Client\Request("POST",
$endpoint,
[ "Api-Key" => $apiKey,
"X-Signature" => $signature,
"Accept" => "application/xml" ]);
try
{ $client = new http\Client;
$client->enqueue($request)->send();
$response = $client->getResponse();
if ($response->getResponseCode() != 200) {
printf("%s returned '%s' (%d)\n",
$response->getTransferInfo("effective_url"),
$response->getInfo(),
$response->getResponseCode()
);
} else {
printf($response->getBody());
}
} catch (Exception $ex) {
printf("Error while sending request, reason: %s\n",$ex->getMessage());
}'
getting following error
Uncaught Error: Class 'http\Client\Request' not found in
You need to add a use statement.
use http\Client\Request;
$request = new Request(blah blah);
Of course I assume you are using Composer autoloader. If not, you will also need to require_once() the file.
You can try using cURL instead of pecl_http. Here is an example:
<?php
// Your API Key and secret
$apiKey = "yourApiKey";
$Secret = "yourSecret";
// Signature is generated by SHA256 (Api-Key + Secret + Timestamp (in seconds))
$signature = hash("sha256", $apiKey.$Secret.time());
$endpoint = "https://api.test.hotelbeds.com/hotel-api/1.0/status";
echo "Your API Key is: " . $apiKey . "<br>";
echo "Your X-Signature is: " . $signature . "<br><br>";
// Example of call to the API
try
{
// Get cURL resource
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $endpoint,
CURLOPT_HTTPHEADER => ['Accept:application/json' , 'Api-key:'.$apiKey.'', 'X-Signature:'.$signature.'']
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Check HTTP status code
if (!curl_errno($curl)) {
switch ($http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE)) {
case 200: # OK
echo "Server JSON Response:<br>" . $resp;
break;
default:
echo 'Unexpected HTTP code: ', $http_code, "\n";
echo $resp;
}
}
// Close request to clear up some resources
curl_close($curl);
} catch (Exception $ex) {
printf("Error while sending request, reason: %s\n",$ex->getMessage());
}
?>
Just make sure that first you uncomment ;extension=php_curl.dll in your php.ini file and restart your server.
We are planning to update our examples in the developer portal because some are outdated or not well documented.

Verify id_token Using a Google API Client Library in PHP

I already have the id_token and it works fine for Calling the token info endpoint but the Google API Client Library for PHP return no result on verifyIdToken() I can't figure out why as no error is thrown any idea on how to fix this?
include_once('google-api-php-client-2.1.1/vendor/autoload.php');
$id_token = trim($_GET['id_token']);
$CLIENT_ID = 'XXXXXXXXXX-o36ncvcpbpo9uiiejb0qXXXXX8820tom.apps.googleusercontent.com';
$client = new Google_Client(['client_id' => $CLIENT_ID]);
$payload = $client->verifyIdToken($id_token);
if ($payload) {
echo 'your id: ' . $userid = $payload['sub'];
// If request specified a G Suite domain:
//$domain = $payload['hd'];
} else {
// Invalid ID token
echo 'invalid token';
}
At the end it still print invalid token

Getting the acess token from Guzzle Oauth authentication

I'm currently trying to develop a connection to the Reddit api through Oauth using Guzzle. I get to the point where I authenticate in Reddit, then I get to the authorization token, but I can't take the access token from the Guzzle response so I can set it as a cookie and using on subsequent requests. My current code looks like this:
public function __construct(){
if(isset($_COOKIE['reddit_token'])){
$token_info = explode(":", $_COOKIE['reddit_token']);
$this->token_type = $token_info[0];
$this->access_token = $token_info[1];
} else {
if (isset($_GET['code'])){
//capture code from auth
$code = $_GET["code"];
//construct POST object for access token fetch request
$postvals = sprintf("code=%s&redirect_uri=%s&grant_type=authorization_code",
$code,
redditConfig::$ENDPOINT_OAUTH_REDIRECT);
//get JSON access token object (with refresh_token parameter)
$token = self::runCurl(redditConfig::$ENDPOINT_OAUTH_TOKEN, $postvals, null, true);
//store token and type
if (isset($token->access_token)){
$this->access_token = $token->access_token;
$this->token_type = $token->token_type;
//set token cookie for later use
$cookie_time = 60 * 59 + time(); //seconds * minutes = 59 minutes (token expires in 1hr)
setcookie('reddit_token', "{$this->token_type}:{$this->access_token}", $cookie_time);
}
} else {
$state = rand();
$urlAuth = sprintf("%s?response_type=code&client_id=%s&redirect_uri=%s&scope=%s&state=%s",
redditConfig::$ENDPOINT_OAUTH_AUTHORIZE,
redditConfig::$CLIENT_ID,
redditConfig::$ENDPOINT_OAUTH_REDIRECT,
redditConfig::$SCOPES,
$state);
//forward user to PayPal auth page
header("Location: $urlAuth");
}
}
This is my authentication flow. The I have the runCurl method that is going to make the guzzle requests:
private function runCurl($url, $postVals = null, $headers = null, $auth = false){
$options = array(
'timeout' => 10,
'verify' => false,
'headers' => ['User-Agent' => 'testing/1.0']
);
$requestType = 'GET';
if ($postVals != null){
$options['body'] = $postVals;
$requestType = "POST";
}
if ($this->auth_mode == 'oauth'){
$options['headers'] = [
'User-Agent' => 'testing/1.0',
'Authorization' => "{$this->token_type} {$this->access_token}"];
}
if ($auth){
$options['auth'] = [redditConfig::$CLIENT_ID, redditConfig::$CLIENT_SECRET];
}
$client = new \GuzzleHttp\Client();
$response = $client->request($requestType, $url, $options);
$body = $response->getBody();
return $body;
}
The problem resides here, the getBody() method returns a stream, and if I use getBody()->getContents() I get a string, none of which can help me.
Any idea on how can I get the access token so I can finish the authentication process?
To answer the question itself - you just need to cast $body to string. It should be a json, so you will also need to json_decode it to use it as an object in the code above. So instead of return $body; in your runCurl, you need to do:
return json_decode((string)$body);
I would recommend to use the official client tho. The code in the question has some unrelated issues, which will make it costy to maintain.

How to get oauth_verification using PECL OAUTH?

I'm trying to get the verification code using php, but as I can see, there is only "manual" (I have to authorize manually) solution for this.
Is there any way to authorize your request token using pecl oauth? I see only getAccessToken and getRequestToken functions, there is nothing for authentication.
The following process requires the verification code at getAccessToken:
private function accessToken( $request_token, $request_token_secret ){
$oauth = $this->oauth;
$access_url = $this->access_url;
$authorize_url = $this->authorize_url;
$consumer_key = $this->consumer_key;
$consumer_secret = $this->consumer_secret;
try {
$oauth = new OAuth( $consumer_key, $consumer_secret );
$oauth->setToken( $request_token, $request_token_secret );
$access_token_info = $oauth->getAccessToken( $access_url, null, VERIFICATION_CODE );
if(!empty($access_token_info)) {
//print_r($access_token_info);
return $access_token_info;
} else {
print "Failed fetching access token, response was: " . $oauth->getLastResponse();
return false;
}
} catch(OAuthException $E) {
echo "Response: ". $E->lastResponse . "\n";
return false;
}
}

Bing Ads api - invalid credentials error

So, our BingAds reporting program, which has been running for many months, is suddenly plagued with 105 (InvalidCredentials) errors. The access token had expired, so I requested a new one, which succeeds, giving me a new access token that expires in the future.
$accessTokenExchangeUrl = "https://login.live.com/oauth20_token.srf";
$accessTokenExchangeParams = array();
$accessTokenExchangeParams['client_id'] = $this->client_id();
$accessTokenExchangeParams['client_secret'] = $this->client_secret();
$accessTokenExchangeParams['grant_type'] = 'refresh_token';
$accessTokenExchangeParams['refresh_token'] = $code;
// Create an HTTP client and execute an HTTP POST request to
// exchange the authorization token for an access token and
// refresh token.
$httpClient = new HttpClient();
$responseJson = $httpClient->postData( $accessTokenExchangeUrl, $accessTokenExchangeParams);
// The response formatted in json
$responseArray = json_decode($responseJson, TRUE);
// If the response contains an access_token element, it was successful.
// If not, an error occurred - throw an exception
if (isset($responseArray['access_token']))
{
return $responseArray;
}
But then using that new token results in a 105 error:
$proxy = \BingAds\Proxy\ClientProxy::ConstructWithCredentials($wsdl, $bingUserName,
$bingPasswd,
$developer_token,
$access_token);
$report = new KeywordPerformanceReportRequest();
$report->Format = ReportFormat::Tsv;
$report->ReportName = 'Keyword Performance Report';
$report->ReturnOnlyCompleteData = false;
<report definition>
$encodedReport = new SoapVar($report, SOAP_ENC_OBJECT, 'KeywordPerformanceReportRequest', $proxy->GetNamespace());
$this->bingReportRequestID = $this->_BingSubmitGenerateReport( $proxy, $encodedReport );
$request = new SubmitGenerateReportRequest();
$request->ReportRequest = $report;
$retval = $proxy->GetService()->SubmitGenerateReport($request)->ReportRequestId;
::> throws a SoapFault
Any ideas? Like I said, it was working fine for months, now suddenly, nothing.
Apparently you are using a refresh_token to authenticate. With the new token you got, you need to generate you new refresh_token and use that one instead.

Categories