I have a requirement to authenticate my site with Linkedin. Am using following code to get linkedin Access token. I can see from the linkedin docs the validity of token is 60 days. Everything works for me am getting access token, i can see the "expires_in" as 5183999 seconds id (60 days).
My problem is when i request for userinfo using this token after 2 days, am getting a error 401 response. The access token lifetime is not stable. I have searched a lot for 401 error, read so may links but not get the exact answer. Why am getting this 401 error ?
Please help me to solve this issue. Your help is much appreciated.
{
errorCode: 0,
message: '[unauthorized] Invalid or expired token.',
requestId: 'P7IR3JY3GZ',
status: 401,
timestamp: 1410937984755
}
// PHP CODE TO GET ACCESS TOKEN
<?php
// Change these
require "config.php";
//define('API_KEY', $ );
//define('API_SECRET', 'secret' );
//define('REDIRECT_URI', 'redirecturl');//http://' . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME']);
define('SCOPE', 'w_messages rw_company_admin r_fullprofile r_emailaddress rw_nus r_network rw_company_admin rw_groups' );
// You'll probably use a database
session_name('linkedin');
session_start();
// OAuth 2 Control Flow
if (isset($_GET['error'])) {
// LinkedIn returned an error
print $_GET['error'] . ': ' . $_GET['error_description'];
exit;
} elseif (isset($_GET['code'])) {
// User authorized your application
if ($_SESSION['state'] == $_GET['state']) {
print_r("ssssssssssssssssssssssssssssssssssssssss");
// Get token so you can make API calls
getAccessToken();
} else {
// CSRF attack? Or did you mix up your states?
exit;
}
} else {
if ((empty($_SESSION['expires_at'])) || (time() > $_SESSION['expires_at'])) {
// Token has expired, clear the state
$_SESSION = array();
}
if (empty($_SESSION['access_token'])) {
// Start authorization process
print_r("ddddddddddddddddddddd");
getAuthorizationCode();
}
}
// Congratulations! You have a valid token. Now fetch your profile
$user = fetch('GET', '/v1/people/~:(id,first-name,last-name,picture-url)');
$pages = fetch2('GET', '/v1/companies:(id,name,logo-url)');
$user->pages = $pages;
$user->accesstoken = $_SESSION['access_token'];
echo "expiry time". $_SESSION['expires_in'];
print_r($pages);
print_r($user);
$SCRIPT = '<script>window.opener.postMessage('.json_encode($user) .',"*");</script>';
session_name('linkedin') ;
session_unset();
echo $SCRIPT;
echo '<h1>', HtmlSpecialChars($user->firstName),
' you have logged in successfully with LinkedIn!</h1>';
echo '<pre>', HtmlSpecialChars(print_r($user, 1)), '</pre>';
//print "Hello $user->firstName $user->lastName.";
exit;
function getAuthorizationCode() {
$params = array('response_type' => 'code',
'client_id' => API_KEY,
'scope' => SCOPE,
'state' => uniqid('', true), // unique long string
'redirect_uri' => REDIRECT_URI,
);
// Authentication request
$url = 'https://www.linkedin.com/uas/oauth2/authorization?' . http_build_query($params);
// Needed to identify request when it returns to us
$_SESSION['state'] = $params['state'];
// Redirect user to authenticate
header("Location: $url");
exit;
}
function getAccessToken() {
$params = array('grant_type' => 'authorization_code',
'client_id' => API_KEY,
'client_secret' => API_SECRET,
'code' => $_GET['code'],
'redirect_uri' => REDIRECT_URI,
);
// Access Token request
$url = 'https://www.linkedin.com/uas/oauth2/accessToken?' . http_build_query($params);
// Tell streams to make a POST request
$context = stream_context_create(
array('http' =>
array('method' => 'POST',
)
)
);
// Retrieve access token information
$response = file_get_contents($url, false, $context);
// Native PHP object, please
$token = json_decode($response);
// Store access token and expiration time
$_SESSION['access_token'] = $token->access_token; // guard this!
$_SESSION['expires_in'] = $token->expires_in; // relative time (in seconds)
$_SESSION['expires_at'] = time() + $_SESSION['expires_in']; // absolute time
return true;
}
function fetch($method, $resource, $body = '') {
$params = array('oauth2_access_token' => $_SESSION['access_token'],
'format' => 'json',
);
// Need to use HTTPS
$url = 'https://api.linkedin.com' . $resource . '?' . http_build_query($params);
// Tell streams to make a (GET, POST, PUT, or DELETE) request
$context = stream_context_create(
array('http' =>
array('method' => $method,
)
)
);
// Hocus Pocus
$response = file_get_contents($url, false, $context);
// Native PHP object, please
return json_decode($response);
}
function fetch2($method, $resource, $body = '') {
$params = array('is-company-admin'=>'true','format' => 'json','oauth2_access_token' => $_SESSION['access_token'],
);
// Need to use HTTPS
$url = 'https://api.linkedin.com' . $resource . '?' . http_build_query($params);
// Tell streams to make a (GET, POST, PUT, or DELETE) request
$context = stream_context_create(
array('http' =>
array('method' => $method,
)
)
);
// Hocus Pocus
$response = file_get_contents($url, false, $context);
// Native PHP object, please
return json_decode($response);
}
Related
I have a sign-in page that refers a user to GitHub for authentication.
After authenticating GitHub successfully returns the code and status as GET parameters to my sign-in page.
Is there a way to get the GitHub user email, name, and handle after getting the access_token?
if(get('action') == 'login')
{
// Generate a random hash and store in the session for security
$_SESSION['state'] = hash('sha256', microtime(TRUE) . rand() . $_SERVER['REMOTE_ADDR']);
unset($_SESSION['access_token']);
$params = array(
'client_id' => OAUTH2_CLIENT_ID,
'redirect_uri' => 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'],
'scope' => 'user',
'state' => $_SESSION['state']
);
// Redirect the user to Github's authorization page
header('Location: ' . $authorizeURL . '?' . http_build_query($params));
die();
}
// When Github redirects the user back here, there will be a "code" and "state" parameter in the query string
if (get('code'))
{
// Verify the state matches our stored state
if (!get('state') || $_SESSION['state'] != get('state')) {
header('Location: ' . $_SERVER['PHP_SELF']);
die();
}
// Exchange the auth code for a token
$token = apiRequest($tokenURL, array(
'client_id' => OAUTH2_CLIENT_ID,
'client_secret' => OAUTH2_CLIENT_SECRET,
'redirect_uri' => 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'],
'state' => $_SESSION['state'],
'code' => get('code')
));
echo var_dump($token) ."<br>";
echo json_encode($token);
$_SESSION['access_token'] = $token->access_token;
header('Location: ' . $_SERVER['PHP_SELF']);
}
}
function apiRequest($url, $post = FALSE, $headers = array())
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if ($post)
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$headers[] = 'Accept: application/json';
if (session('access_token'))
$headers[] = 'Authorization: Bearer ' . session('access_token');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
return json_decode($response);
}
function get($key, $default = NULL)
{
return array_key_exists($key, $_GET) ? $_GET[$key] : $default;
}
function session($key, $default = NULL)
{
return array_key_exists($key, $_SESSION) ? $_SESSION[$key] : $default;
}
You need to call the Github API with the access token to access the current User
So if you already have the access_token available and it's saved sucessfully in $_SESSION['access_token'] - it will be used automatically for all further requests done by apiRequest() Method Calls
$user = apiRequest("https://api.github.com/user');
var_dump($user);
// $user->name should be available in response
When I tested your code - the apiRequest-Method returned an error (var_dump($response))
Request forbidden by administrative rules. Please make sure your request has a User-Agent header (http://developer.github.com/v3/#user-agent-required). Check https://developer.github.com for other possible causes.
Just add a User-Agent to the headers[] array in the method (e.g. right below the added Accept: Header)
$headers[] = 'User-Agent: PHP Api Call';
... and your API-Call will work ;)
Edit: because you set 'scope' => 'user', in your initial Auth-Request - you requested Access to the User-Data - but nothing more (see OAuth-App-Scopes if you need additional permissions/info)
I'm trying to signin the user just with PHP and curl, without any external libraries for Twitter authentication. I follow these Twitter instructions. But I can't figure out how to complete step 3.
1. Obtaining a request token (done)
2. Redirecting the user (done)
3. Converting the request token to an access token. (done * problem)
Here is my code:
// API SETTINGS
$consumerSecret = 'xxx';
$consumerKey = 'xxx';
$oauth_signature_method = 'HMAC-SHA1';
if (!isset($_GET['oauth_verifier'])) {
// STEP 1 - TWITTER OBTAINING A REQUEST TOKEN
$callbackUrl = 'http://localhost/skeletons/webiik/example/login/';
$url = 'https://api.twitter.com/oauth/request_token';
// Data we will send
$data = [
'oauth_callback' => $callbackUrl,
'oauth_consumer_key' => $consumerKey,
'oauth_signature_method' => $oauth_signature_method,
'oauth_timestamp' => time(),
'oauth_nonce' => $token->generate(3),
'oauth_version' => '1.0',
];
// Sort data alphabetically, because Twitter requires that
ksort($data);
// Generate signature and add it to data array
$signData = 'POST&' . urlencode($url) . '&' . urlencode(http_build_query($data));
$secret = '';
$signKey = urlencode($consumerSecret) . '&' . urlencode($secret);
$data['oauth_signature'] = base64_encode(hash_hmac('sha1', $signData, $signKey, true));
// Prepare http headers from data
$httpHeaders = [];
foreach ($data as $key => $value) {
$httpHeaders[] = urlencode($key) . '="' . urlencode($value) . '"';
}
// Add OAuth header with all data
$httpHeaders = 'Authorization: OAuth ' . implode(', ', $httpHeaders);
// Send post request to Twitter API with http headers and data
$res = $http->post($url, ['httpHeaders' => [$httpHeaders]], []);
// If we got some error, show error message and stop
if (count($res['err']) > 0) {
echo $res['err'];
exit;
}
// Prepare data for step 2 and 3 from Twitter's response
parse_str($res['body'], $res);
$oauth_callback_confirmed = $res['oauth_callback_confirmed'];
$oauth_request_token = $res['oauth_token'];
// Store oauth_token_secret into session, we will need it in step 3
$this->sessions->setToSession('oauth_token_secret', $res['oauth_token_secret']);
$this->sessions->setToSession('oauth_token', $oauth_request_token);
// STEP 2 - REDIRECTING THE USER TO TWITTER LOGIN
header('HTTP/1.1 302 Found');
header('Location: https://api.twitter.com/oauth/authenticate?oauth_token=' . urlencode($oauth_request_token));
}
// STEP 3 - CONVERTING THE REQUEST TOKEN TO AN ACCESS TOKEN
$url = 'https://api.twitter.com/oauth/access_token';
$oauth_token = $_GET['oauth_token'];
$oauth_verifier = $_GET['oauth_verifier'];
// Data we will send
$data = [
'oauth_consumer_key' => $consumerKey,
'oauth_nonce' => $token->generate(3),
'oauth_signature_method' => $oauth_signature_method,
'oauth_timestamp' => time(),
'oauth_token' => $oauth_token,
'oauth_version' => '1.0',
];
// Sort data alphabetically, because Twitter requires that
ksort($data);
// Generate signature and add it to data array
$signData = 'POST&' . urlencode($url) . '&' . urlencode(http_build_query($data));
$secret = $this->sessions->getFromSession('oauth_token_secret');
$signKey = urlencode($consumerSecret) . '&' . urlencode($secret);
$data['oauth_signature'] = base64_encode(hash_hmac('sha1', $signData, $signKey, true));
// Sort data also with added oauth_signature, just for sure
ksort($data);
// Prepare http headers from data
$httpHeaders = [];
foreach ($data as $key => $value) {
$httpHeaders[] = urlencode($key) . '="' . urlencode($value) . '"';
}
// Add OAuth header with all data
$httpHeaders = ['Authorization: OAuth ' . implode(', ', $httpHeaders)];
$httpHeaders[] = 'Content-Length: ' . strlen('oauth_verifier=' . urlencode($oauth_verifier));
$httpHeaders[] = 'Content-Type: application/x-www-form-urlencoded';
// Add oauth_verifier to POST data
$postData = ['oauth_verifier' => $oauth_verifier];
// Send post request to Twitter API with http headers and data
$res = $http->post($url, ['httpHeaders' => $httpHeaders], $postData);
// If we got some error, show error message and stop
if (count($res['err']) > 0) {
echo $res['err'];
exit;
}
print_r($res);
Edit 1:
$http is just object that creates standard curl requests. In third step the curl request looks like:
$curl = curl_init($url);
curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FAILONERROR => 1,
CURLOPT_VERBOSE => 1,
CURLOPT_HEADER => 1,
CURLOPT_HTTPHEADER => $arrayOfHttpHeaders,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => http_build_query($postData),
]);
$response = curl_exec($curl);
// Process response...
Edit 2:
I just updated the code to be more accurate to Twitter's example. Now I really don't know where can be the problem.
Edit 3:
Solution: The code is ok. I had problem with router, which added slash at the end of URL. And I grabbed verifier_token with that slash.
I'm new at Stripe integration. I've read the API documentation for Stripe and here is the OAuth flow. But I still don't receive any OAuth access token. Can someone explain how can I receive an access token? Thanks!
if (isset($_GET['code'])) { // Redirect w/ code
$code = $_GET['code'];
$token_request_body = array(
'grant_type' => 'authorization_code',
'client_id' => 'ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7',
'code' => $code,
'client_secret' => ''
);
$req = curl_init(TOKEN_URI);
curl_setopt($req, CURLOPT_RETURNTRANSFER, true);
curl_setopt($req, CURLOPT_POST, true );
curl_setopt($req, CURLOPT_POSTFIELDS, http_build_query($token_request_body));
// TODO: Additional error handling
$respCode = curl_getinfo($req, CURLINFO_HTTP_CODE);
$resp = json_decode(curl_exec($req), true);
curl_close($req);
echo $resp['access_token'];
} else if (isset($_GET['error'])) { // Error
echo $_GET['error_description'];
} else { // Show OAuth link
$authorize_request_body = array(
'response_type' => 'code',
'scope' => 'read_write',
'client_id' => 'ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7'
);
$url = AUTHORIZE_URI . '?' . http_build_query($authorize_request_body);
echo "<a href='$url'>Connect with Stripe</a>";
}
You should use an OAuth 2.0 client library for this instead of attempting to roll this yourself as suggested by Stripe:
https://stripe.com/docs/connect/standalone-accounts#sample-code
There are many of these, but this is a pretty good option:
https://github.com/thephpleague/oauth2-client
You could modify this example and retrieve the account ID like so:
$provider->getResourceOwner($accessToken)->getId();
Once you retrieve the account ID, you'd store and use this to authenticate as the connected account as suggested by Stripe:
https://stripe.com/docs/connect/authentication#authentication-via-the-stripe-account-header
they actually have, what seems like, an official github library
and they have an example for the oauth thing
just missing in the docs for whatever reason...
https://github.com/stripe/stripe-php/blob/master/examples/oauth.php
in case they delete it, i include the file here, note: they make use of their library, so you have to install it prior to this to work
<?php
require('../init.php');
\Stripe\Stripe::setApiKey(getenv('STRIPE_SECRET_KEY'));
\Stripe\Stripe::setClientId(getenv('STRIPE_CLIENT_ID'));
if (isset($_GET['code'])) {
// The user was redirected back from the OAuth form with an authorization code.
$code = $_GET['code'];
try {
$resp = \Stripe\OAuth::token([
'grant_type' => 'authorization_code',
'code' => $code,
]);
} catch (\Stripe\Error\OAuth\OAuthBase $e) {
exit("Error: " . $e->getMessage());
}
$accountId = $resp->stripe_user_id;
echo "<p>Success! Account <code>$accountId</code> is connected.</p>\n";
echo "<p>Click here to disconnect the account.</p>\n";
} elseif (isset($_GET['error'])) {
// The user was redirect back from the OAuth form with an error.
$error = $_GET['error'];
$error_description = $_GET['error_description'];
echo "<p>Error: code=" . htmlspecialchars($error, ENT_QUOTES) . ", description=" . htmlspecialchars($error_description, ENT_QUOTES) . "</p>\n";
echo "<p>Click here to restart the OAuth flow.</p>\n";
} elseif (isset($_GET['deauth'])) {
// Deauthorization request
$accountId = $_GET['deauth'];
try {
\Stripe\OAuth::deauthorize([
'stripe_user_id' => $accountId,
]);
} catch (\Stripe\Error\OAuth\OAuthBase $e) {
exit("Error: " . $e->getMessage());
}
echo "<p>Success! Account <code>" . htmlspecialchars($accountId, ENT_QUOTES) . "</code> is disconnected.</p>\n";
echo "<p>Click here to restart the OAuth flow.</p>\n";
} else {
$url = \Stripe\OAuth::authorizeUrl([
'scope' => 'read_only',
]);
echo "Connect with Stripe\n";
}
Since the Google Login Auth is disabled since last week I'm trying to get oAuth 2.0 working with a service account. We want to give users on our internal web application the oppurtunity to set there Out of Office.
I downloaded the lastest Google APIs Client Library for PHP. In the Google Developer Console, I have created a new project for my application and created a Service account credentials. I have also enabled the API service: Admin SDK in the Developer Console.
I have granted the account user ID access to the correct scopes (I think):
When I use the service-account.php example and change the details, I recieve an JSON with an access token, but when I do an CURL request (same as before) to get the e-mail settings from a user, the error "You are not authorized to access this API." occur.
My code:
<?php
include_once "templates/base.php";
require_once realpath(dirname(__FILE__) . '/../src/Google/autoload.php');
$client_id = '124331845-DELETEDPART-hbh89pbgl20citf6ko.apps.googleusercontent.com'; //Client ID
$service_account_name = '124331845-DELETEDPART-89pbgl20citf6ko#developer.gserviceaccount.com'; //Email Address
$key_file_location = 'globaltext-4ce09b20cb73.p12'; //key.p12
$client = new Google_Client();
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://apps-apis.google.com/a/feeds/emailsettings/2.0/'),
$key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$aOutput = json_decode($client->getAccessToken());
$strEmailAdresSplit = explode('#', "FIRSTNAME.LASTNAME#DOMAIN.EXTENSION");
$strDomein = $strEmailAdresSplit[1];
$strAlias = $strEmailAdresSplit[0];
$resConnectionJobs = curl_init();
$aHeader = array();
$aHeader[] = 'Authorization: Bearer '.$aOutput->access_token;
$aHeader[] = 'Content-Type: application/atom+xml';
curl_setopt($resConnectionJobs, CURLOPT_URL, "https://apps-apis.google.com/a/feeds/emailsettings/2.0/DOMAIN.EXTENSION/FIRSTNAME.LASTNAME/vacation");
curl_setopt($resConnectionJobs, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($resConnectionJobs, CURLOPT_HTTPHEADER, $aHeader);
curl_setopt($resConnectionJobs, CURLOPT_RETURNTRANSFER, true);
curl_setopt($resConnectionJobs, CURLOPT_HEADER, false);
$oCurlData = curl_exec($resConnectionJobs);
curl_close($resConnectionJobs);
echo $oCurlData;
?>
Are you certain your credentials are OK?
Please try the following procedure to make sure you have the right credentials.
Creating your API keys
Go to the developer's console and follow these steps:
Select your project
Choose menu item "APIs & auth"
Choose menu item "Registered app"
Register an app of type "web application"
Choose one of the following options, depending on what kind of app you're creating. Server side languages should use this option :
Key for server apps (with IP locking)
Getting access token & refresh token
Create a file that contains the following code :
<?php
if (isset($_GET['code'])) {
// try to get an access token
$code = $_GET['code'];
$url = 'https://accounts.google.com/o/oauth2/token';
$params = array(
"code" => $code,
"client_id" => YOUR_CLIENT_ID,
"client_secret" => YOUR_CLIENT_SECRET,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"grant_type" => "authorization_code"
);
$ch = curl_init();
curl_setopt($ch, constant("CURLOPT_" . 'URL'), $url);
curl_setopt($ch, constant("CURLOPT_" . 'POST'), true);
curl_setopt($ch, constant("CURLOPT_" . 'POSTFIELDS'), $params);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($info['http_code'] === 200) {
header('Content-Type: ' . $info['content_type']);
return $output;
} else {
return 'An error happened';
}
} else {
$url = "https://accounts.google.com/o/oauth2/auth";
$params = array(
"response_type" => "code",
"client_id" => YOUR_CLIENT_ID,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"scope" => "https://www.googleapis.com/auth/plus.me"
);
$request_to = $url . '?' . http_build_query($params);
header("Location: " . $request_to);
}
Now, replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with your client ID and client secret.
Make sure your scope is correct. For example, it should be https://www.googleapis.com/auth/analytics if you want to get access to Analytics.
If you run the file, you should get an OAuth2 approval screen.
If you now press Accept, you should get a result that looks like this:
{
"access_token" : YOUR_ACCESS_TOKEN,
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : YOUR_REFRESH_TOKEN
}
The result may contain additional fields, depending on which scope you're applying for.
Connecting with Google's systems in background
Once you get the above to work, your application needs to implement the following workflow:
1) Check if your input contains a GET parameter named "code". If "code" is present, get a new access token and repeat this step (refresh your page)
If "code" is not present, go to step 2.
2) Check if you have credentials stored for your service. If credentials are present, check if your access token has expired or will expire soon. Then go to step 3. If credentials are not present, go to the auth path of your service to get the auth code and go back to step 1 (make sure Google redirects to your current URL).
3) If refresh is needed, refresh your page and go back to step 1.
If refresh is not needed, you're ready to actually do what you wanted to do in the first place.
Google's PHP library takes care if the oAuth2 flow for you, however. If you're using their library, each of the steps in the 3-step process are taken care of by the library and you should just be able to do whatever you want to do with Google's services straight away. I use this strategy myself in my Google Adwords dashboard.
You can, however, just write your custom library and connect with the service directly. Herebelow is some dev code from a project I wrote a few months ago. While it doesn't work out of the box (since it's a controller that's part of a larger application), it should help you understand the flow that Google's library takes care of under the hood.
namespace Application;
class Controller_API_Google_Youtube extends Controller_API {
public function read() {
$scope = "https://www.googleapis.com/auth/youtube";
$this->doOauth($scope);
}
function doOauth($scope) {
$oauth2Credentials = JSON_File::load(__DIR__ . DIRECTORY_SEPARATOR . 'Config.json');
$paths = array(
'token' => 'https://accounts.google.com/o/oauth2/token',
'auth' => "https://accounts.google.com/o/oauth2/auth"
);
$refreshtime = 300;
if (isset($_GET['code'])) {
// Get access code
$query = $_GET;
unset($query['code']);
if (count($query) > 0) {
$query = '?' . http_build_query($query);
} else {
$query = '';
}
$client = \PowerTools\HTTP_Client::factory(
array(
'maps' => array(
'url' => $paths['token'],
'returntransfer' => 1,
'post' => true,
'postfields' => array(
'code' => $_GET['code'],
"client_id" => $oauth2Credentials['client_id'],
"client_secret" => $oauth2Credentials['client_secret'],
"redirect_uri" => HTTP_PROTOCOL . URL_PATH . $query,
"grant_type" => "authorization_code"
)
)
)
)->execute();
$responses = $client->getResponses();
$response = array_pop($responses);
$info = $response['maps']->getInfo();
$content = $response['maps']->getContent();
if ($info['http_code'] === 200) {
$output = JSON::decode($content);
$oauth2Credentials[$scope] = array();
$oauth2Credentials[$scope]['expires'] = time() + $output['expires_in'];
$oauth2Credentials[$scope]['access_token'] = $output['access_token'];
$oauth2Credentials[$scope]['refresh_token'] = $output['refresh_token'];
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'Config.json', JSON::encode($oauth2Credentials));
header("Location: " . HTTP_PROTOCOL . URL_PATH . $query);
} else {
echo "Something went wrong";
}
} elseif (!isset($oauth2Credentials[$scope])) {
// Get auth code
header("Location: " . $paths['auth'] . '?' . http_build_query(
array(
"response_type" => "code",
"client_id" => $oauth2Credentials['client_id'],
"redirect_uri" => HTTP_PROTOCOL . DOMAIN_PATH,
"scope" => $scope
)
));
} elseif ($oauth2Credentials[$scope]['expires'] - $refreshtime < time()) {
// Refresh access code
$client = \PowerTools\HTTP_Client::factory(
array(
'maps' => array(
'url' => $paths['token'],
'returntransfer' => 1,
'post' => true,
'postfields' => array(
"client_id" => $oauth2Credentials['client_id'],
"client_secret" => $oauth2Credentials['client_secret'],
"refresh_token" => $oauth2Credentials[$scope]['refresh_token'],
"grant_type" => "refresh_token"
)
)
)
)->execute();
$responses = $client->getResponses();
$response = array_pop($responses);
$info = $response['maps']->getInfo();
$content = $response['maps']->getContent();
if ($info['http_code'] === 200) {
$output = JSON::decode($response['maps']->getContent());
$oauth2Credentials[$scope]['expires'] = time() + $output['expires_in'];
$oauth2Credentials[$scope]['access_token'] = $output['access_token'];
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'Config.json', JSON::encode($oauth2Credentials));
$this->read();
} else {
$this->output = array("error" => "Something went wrong");
}
} else {
$this->doSomethinguseful($oauth2Credentials, $scope);
}
return $this;
}
function doSomethinguseful($oauth2Credentials, $scope) {
// https://developers.google.com/youtube/v3/sample_requests?hl=nl
$client = \PowerTools\HTTP_Client::factory(
array(
'maps' => array(
'useragent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13',
'url' => 'https://www.googleapis.com/youtube/v3/channels?part=contentDetails&mine=true',
'returntransfer' => true,
'httpheader' => array(
'Authorization: Bearer ' . $oauth2Credentials[$scope]['access_token'],
'Accept-Encoding: gzip, deflate'
)
)
)
)->execute();
$responses = $client->getResponses();
$response = array_pop($responses);
$content = $response['maps']->getContent();
$this->output = JSON::decode(gzdecode($content));
}
}
It looks like you may be running into a problem I had as well.
The call to Google_Auth_AssertionCredentials actually requires more parameters than you're sending to work with a service account. (At least, it did in my case.)
You need to pass enough parameters to include sub (which user to take actions on account of).
Without that, I always got an access denied. This clearly isn't obvious, since there's even been a function added to the php library, loadServiceAccountJson, which is supposed to set up a service account client connection, but breaks because it doesn't set sub either.
See working code here: Google php client library loadServiceAccountJson broken - fix enclosed
I am using this code to access the LinkedIn API and it's working perfectly, but it only gets details like first name, last-name, headline, and email.
I want to get the user's connections, company name, company type, company size, positions, and industry.
How can I get these details through the LinkedIn API ?
<?php
// Change these
define('API_KEY', [api_key]);
define('API_SECRET', [api_secret]);
define('REDIRECT_URI', 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME']);
define('SCOPE', 'r_fullprofile r_emailaddress rw_nus r_network');
// You'll probably use a database
session_name('linkedin');
session_start();
// OAuth 2 Control Flow
if (isset($_GET['error'])) {
// LinkedIn returned an error
print $_GET['error'] . ': ' . $_GET['error_description'];
exit;
} elseif (isset($_GET['code'])) {
// User authorized your application
if ($_SESSION['state'] == $_GET['state']) {
// Get token so you can make API calls
getAccessToken();
} else {
// CSRF attack? Or did you mix up your states?
exit;
}
} else {
if ((empty($_SESSION['expires_at'])) || (time() > $_SESSION['expires_at'])) {
// Token has expired, clear the state
$_SESSION = array();
}
if (empty($_SESSION['access_token'])) {
// Start authorization process
getAuthorizationCode();
}
}
$user = fetch('GET', 'http://api.linkedin.com/v1/people/id=12345/connections');
print_r($user);
$name = $user->firstName.' '.$user->lastName;
$email = $user->emailAddress;
$occupation = $user->headline;
exit;
function getAuthorizationCode() {
$params = array('response_type' => 'code',
'client_id' => API_KEY,
'scope' => SCOPE,
'state' => uniqid('', true), // unique long string
'redirect_uri' => REDIRECT_URI,
);
// Authentication request
$url = 'https://www.linkedin.com/uas/oauth2/authorization?' . http_build_query($params);
// Needed to identify request when it returns to us
$_SESSION['state'] = $params['state'];
// Redirect user to authenticate
header("Location: $url");
exit;
}
function getAccessToken() {
$params = array('grant_type' => 'authorization_code',
'client_id' => API_KEY,
'client_secret' => API_SECRET,
'code' => $_GET['code'],
'redirect_uri' => REDIRECT_URI,
);
// Access Token request
$url = 'https://www.linkedin.com/uas/oauth2/accessToken?' . http_build_query($params);
// Tell streams to make a POST request
$context = stream_context_create(
array('http' =>
array('method' => 'POST',
)
)
);
// Retrieve access token information
$response = file_get_contents($url, false, $context);
// Native PHP object, please
$token = json_decode($response);
// Store access token and expiration time
$_SESSION['access_token'] = $token->access_token; // guard this!
$_SESSION['expires_in'] = $token->expires_in; // relative time (in seconds)
$_SESSION['expires_at'] = time() + $_SESSION['expires_in']; // absolute time
return true;
}
function fetch($method, $resource, $body = '') {
$params = array('oauth2_access_token' => $_SESSION['access_token'],
'format' => 'json',
);
// Need to use HTTPS
//$url = 'https://api.linkedin.com' . $resource . '?' . http_build_query($params);
$url = $resource . '?' . http_build_query($params);
// Tell streams to make a (GET, POST, PUT, or DELETE) request
$context = stream_context_create(
array('http' =>
array('method' => $method,
)
)
);
// Hocus Pocus
$response = file_get_contents($url, false, $context);
// Native PHP object, please
return json_decode($response);
}
?>
For 1st degree connections, you may only retrieve basic profile fields and you can use like this. for reference http://developer.linkedin.com/documents/connections-api
$user = fetch('GET', 'http://api.linkedin.com/v1/people/~/connections:
(id,first-name,last-name,location:(name),picture-url)');