I'm accessing dropbox using OAuth 2.0 where it will gain an access token after succesfully authenticating a user. When I have successfully authenticating a user, I'm stuck at the success page where I have the authorization code. How do I redirect to my localhost and convert it to access token? I'm developing using php.
$appInfo = dbx\AppInfo::loadFromJsonFile("config.json");
$webAuth = new dbx\WebAuthNoRedirect($appInfo, "PHP-Example/1.0");
$authorizeUrl = $webAuth->start();
//echo $authorizeUrl;
header("Location:$authorizeUrl");
//$authCode = \trim(\readline("Enter the authorization code here: "));
$authCode = $_GET;
list($accessToken, $dropboxUserId) = $webAuth->finish($authcode);
print "Access Token: " . $accessToken . "\n";
$dbxClient = new dbx\Client($accessToken, "PHP-Example/1.0");
$accountInfo = $dbxClient->getAccountInfo();
print_r($accountInfo);
You're using WebAuthNoRedirect, which doesn't do redirection back to your app. You need to use WebAuth (which does do the redirection). If you look at the web-file-browser.php example in the PHP SDK download, you'll see an example that looks like this:
function getWebAuth()
{
list($appInfo, $clientIdentifier, $userLocale) = getAppConfig();
$redirectUri = getBaseUrl()."/dropbox-auth-finish";
$csrfTokenStore = new dbx\ArrayEntryStore($_SESSION, 'dropbox-auth-csrf-token');
return new dbx\WebAuth($appInfo, $clientIdentifier, $redirectUri, $csrfTokenStore, $userLocale);
}
I would start from that sample, as it's a complete end-to-end web app.
Related
I'm using 'Google_Client' class to authenticate access to adwords api so:
$REDIRECT_URI = 'http://localhost/GoogleAdwords/auth.php';
$client = new Google_Client();
$client->setApplicationName("App name");
$SCOPES = array('https://www.googleapis.com/auth/adwords'
);
$client->setIncludeGrantedScopes(true);
$client->setAccessType('offline');
$client->setRedirectUri($REDIRECT_URI);
$client->setScopes($SCOPES);
try{
$oauth2 = (new OAuth2TokenBuilder())
->withClientId($OAuthCredentials['clientId'])
->withClientSecret($OAuthCredentials['clientSecret'])
->withRefreshToken($client->getRefreshToken())
->build();
}catch(Exception $err){
//redirect("auth.php");
echo $err;
}
After authentication:
$oauth2 = (new OAuth2TokenBuilder())
->withClientId($OAuthCredentials['clientId'])
->withClientSecret($OAuthCredentials['clientSecret'])
->withRefreshToken($client->getRefreshToken())
->build();
$session = (new AdWordsSessionBuilder())
->fromFile()
->withOAuth2Credential($oauth2)
->build();
$adWordsServices = new AdWordsServices();
$managedCustomerService = $adWordsServices->get($session, ManagedCustomerService::class);
$selector = new Selector();
$selector->setFields(['CustomerId', 'Name']);
$selector->setOrdering([new OrderBy('CustomerId')]);
try{
$mccAccounts = $managedCustomerService->get($selector);
}catch(Exchange $e){
// echo $e->getMessage();
}
I'm pretty sure that the client is authenticated as I can get refreshToken and access token. But I'm getting this error:
Client error: `POST https://www.googleapis.com/oauth2/v4/token` resulted in a `401 Unauthorized` response: { "error": "unauthorized_client", "error_description": "Unauthorized" }
What could be the problem here? Am I missing something?
EDIT:
Using the same $client to access user information and shopping content works fine, but that's not the case for adwords.
This works for me, but I don't understand Google's libraries well enough to say if it's all necessary, maybe someone else can trim the fat.
$client = new \Google_Client();
$client->setApplicationName('NAME_HERE');
$client->setAuthConfig(__DIR__ . '/../Credentials/oauth.json');
$client->setAccessType('offline');
$client->setApiFormatV2(2);
//// Load previously authorized credentials from a file.
$oAuth = json_decode(file_get_contents(__DIR__ . '/../Credentials/oauth.json'), true);
$accessToken = json_decode(file_get_contents(__DIR__ . '/../Credentials/token.json'), true);
$client->setAccessToken($accessToken);
$oauth2 = (new OAuth2TokenBuilder())
->withClientId($oAuth['installed']['client_id'])
->withClientSecret($oAuth['installed']['client_secret'])
->withRefreshToken($client->getRefreshToken())
->build();
$session = (new AdWordsSessionBuilder())
->withDeveloperToken('TOKEN_HERE')
->withClientCustomerId("CUSTOMER_ID_HERE")
->withOAuth2Credential($oauth2)
->build();
$adWordsServices = new AdWordsServices();
$managedCustomerService = $adWordsServices->get($session, ManagedCustomerService::class);
$selector = new Selector();
$selector->setFields(['CustomerId', 'Name']);
$selector->setOrdering([new OrderBy('CustomerId')]);
$mccAccounts = $managedCustomerService->get($selector);
dd($mccAccounts) ;
I am receiving an error message when trying to execute youtube analytics API.
A service error occurred: Error calling GET
https://www.googleapis.com/youtube/analytics/v1/reports?ids=channel%3D%3DUCaayLD9i5x4MmIoVZxXSv_g&start-date=2016-08-01&end-date=2016-08-07&metrics=views&dimensions=7DayTotals:
(403) Forbidden
Here is my code:
require_once __DIR__.'\google-api-php-client-1-master\src\Google\autoload.php';
require_once __DIR__.'\google-api-php-client-1-master\src\Google\Client.php';
require_once __DIR__.'\google-api-php-client-1-master\src\Google\Service\YouTube.php';
session_start();
$key = file_get_contents('mykey.json');
$OAUTH2_CLIENT_ID = 'xx-xx-xx';
$OAUTH2_CLIENT_SECRET = 'xxx';
$scope = array("https://www.googleapis.com/auth/youtube.force-ssl", "https://www.googleapis.com/auth/youtubepartner-channel-audit", "https://www.googleapis.com/auth/youtube", "https://www.googleapis.com/auth/youtube.readonly", "https://www.googleapis.com/auth/yt-analytics.readonly", "https://www.googleapis.com/auth/yt-analytics-monetary.readonly","https://www.googleapis.com/auth/youtubepartner");
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setAccessType('offline');
$client->setAccessToken($key);
$client->setScopes($scope);
if ($client->getAccessToken()) {
//Check to see if our access token has expired. If so, get a new one and save it to file for future use.
if($client->isAccessTokenExpired()) {
//refresh your access token if it's expired
$newToken = json_decode($client->getAccessToken());
$client->refreshToken($newToken->refresh_token);
file_put_contents('mykey.json', $client->getAccessToken());
}
$analytics = new Google_Service_YouTubeAnalytics($client);
$channel_url = 'UCaayLD9i5x4MmIoVZxXSv_g';
$ids = 'channel==' . $channel_url . '';
$end_date = '2016-08-07';
$start_date = '2016-08-01';
$optparams = array(
'dimensions' => '7DayTotals',
);
$metric = 'views';
$api = $analytics->reports->query($ids, $start_date, $end_date, $metric, $optparams);
echo '<pre>';print_r($api);die;
}
I have already enable 'youtube analytic API' and I get the access_token from here
What is wrong with my code ,Or do we need to do some more stuff to get rid from this?
Looking at your code, it seems that you are generating a new access token at the point you save it to file (invalidating the first one).
Try :
if($client->isAccessTokenExpired()) {
//refresh your access token if it's expired
$newToken = json_decode($client->getAccessToken());
$client->refreshToken($newToken->refresh_token);
file_put_contents('mykey.json', $newToken);
}
I had a problem on making the Google Drive API work. I want to allow public user to search on my file list and upload files to my Google Drive.
I created an API key on my developer console and added it to the following script and try to read a list of my files, but didn't work. It returned "500 Internal Server Error". Do I miss anything?
require_once 'google-api-php-client/src/Google/autoload.php';
$client = new Google_Client();
$client->setDeveloperKey("MY_API_KEY");
$client->addScope("https://www.googleapis.com/auth/drive");
$dr_service = new Google_Service_Drive($client);
$dr_results = $dr_service->files->listFiles(array('maxResults' => 10))
I tried to use ClientID (see the following code) and it works but I don't want to prompt the user to login to their google account and I want them to do everything on my account. Or how can I call the oauth with my account without prompting the user?
session_start();
require_once 'google-api-php-client/src/Google/autoload.php';
$client = new Google_Client();
// Get your credentials from the console
$client->setClientId('MY_CLIENT_ID');
$client->setClientSecret('MY_CLIENT_SECRET');
$client->setRedirectUri('MY_URL');
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
$authUrl = $client->createAuthUrl();
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
header('Location: http://MY_URL');
}
if (!$client->getAccessToken() && !isset($_SESSION['token'])) {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
if (isset($_SESSION['token'])) {
print "<a class='logout' href='".$_SERVER['PHP_SELF']."?logout=1'>LogOut</a><br>";
$client->setAccessToken($_SESSION['token']);
$service = new Google_Service_Drive($client);
var_dump($service->files->ListFiles());
}
download the files from here google drive client in a folder google_drive.Then try this code
include the three files .
require 'google_drive/Google_Client.php';
require 'google_drive/contrib/Google_DriveService.php';
require 'google_drive/socialmedia_oauth_connect.php';
create new object of the classess.
$client_gd = new Google_Client();
$service = new Google_DriveService($client_gd);
$file=new Google_DriveFile();
set access token
if(isset($_GET['code']))
{
$authCode = $_REQUEST['code'];
$accessToken = $client_gd->authenticate($authCode);
$_SESSION['access_token_gd']=$accessToken;
$client_gd->setAccessToken($accessToken);
$about = $service->about->get();
$user=$about['permissionId'];
$_SESSION['gd_user']=$user;
$_SESSION['user_info_gd']=$about;
header('location:'.HOME.'?index_gd=1');
}
authenticate with google drive
$authUrl = $client_gd->createAuthUrl();
//$clientid = $gdsettings->gdclient_id;
// $clientsec = $gdsettings->gdclient_secret;
$redirecturi = HOME.'index.php';
$oauth = new socialmedia_oauth_connect();
$oauth->provider="Google";
global $apiConfig;
$oauth->client_id = $apiConfig['oauth2_client_id'];
$oauth->client_secret = $apiConfig['oauth2_client_secret'];
$oauth->scope="https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/drive.appdata https://www.googleapis.com/auth/drive.readonly https://www.googleapis.com/auth/drive.apps.readonly https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.me https://docs.google.com/feeds/ https://docs.googleusercontent.com/ https://spreadsheets.google.com/feeds/";
$oauth->redirect_uri = $apiConfig['oauth2_redirect_uri'];
$oauth->approval_prompt = "force";
$oauth->Initialize();
$oauth->Authorize();
get the files
$accessToken=$_SESSION['access_token_gd'];
$client_gd->setAccessToken($accessToken);
//print_r($client_gd->getAccessToken());
//List of files
$arr = array();
$files = $service->files->listFiles();
$about = $service->about->get();
$user=$about['permissionId'];
//$_SESSION['gd_user']=$user;
//$_SESSION['user_info_gd']=$about;
$drivefiles = $files["items"];
foreach($drivefiles as $divefl )
{
echo $divefl['title'];
}
here is the full description you can read google drive client integration
I have the following code
<?php
// Include DropBox API
require_once "dropbox-sdk/Dropbox/autoload.php";
use \Dropbox as dbx;
// Settings for DropBox
$appInfo = dbx\AppInfo::loadFromJsonFile("config.json");
$webAuth = new dbx\WebAuthNoRedirect($appInfo, "PHP-Example/1.0");
$authCode = \trim(\readline("A-WALID-KEY-HERE"));
list($accessToken, $dropboxUserId) = $webAuth->finish($authCode);
print "Access Token: " . $accessToken . "\n";
?>
Bud i get this error when i run the code.
Call to undefined function readline()
What am I doing wrong?
It sounds from your comment like you're trying to run this as a web app. If so, you're going to run into trouble. This looks like the command-line app example code, which is why it uses readline (which reads input from the command-line).
You might want to start from the web-file-browser example that ships with the SDK. This is meant to be run as a web app and should show you to how to do (among other things) authentication in the browser.
I had the same problem with the same code. You have forgotten to add this:
$authorizeUrl = $webAuth->start();
just right after this line:
$webAuth = new dbx\WebAuthNoRedirect($appInfo, "PHP-Example/1.0");
What you have to do is to use the created link stored in the variable $authorizeUrl to get the authorization code.
After doing this you need to use the authorization code to generate a token. For this comment the part of your code like that:
<?php
// Include DropBox API
require_once "dropbox-sdk/Dropbox/autoload.php";
use \Dropbox as dbx;
// Settings for DropBox
//$appInfo = dbx\AppInfo::loadFromJsonFile("config.json");
//$webAuth = new dbx\WebAuthNoRedirect($appInfo, "PHP-Example/1.0");
//**$authorizeUrl = $webAuth->start();**
$authCode = \trim(\readline("**A-WALID-KEY-HERE**"));
list($accessToken, $dropboxUserId) = $webAuth->finish($authCode);
print "Access Token: " . $accessToken . "\n";
?>
Once you get the token save it somewhere safe and comment also the rest of the lines. Then you can access dropbox with no problem. For example:
$dbxClient = new dbx\Client($accessToken, "PHP-Example/1.0");
$accountInfo = $dbxClient->getAccountInfo();
I followed again THIS TUTORIAL to upload a file on Google Drive with php, directly from my REMOTE SERVER: so I have created new API Project from Google API Console, enabled Drive API service, requested OAuth Client ID and Client Secret, wrote them in a script, then upload it together with Google APIs Client Library for PHP folder to this http://www.MYSERVER.com/script1.php, to retrieve Auth code:
<?php
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_DriveService.php';
$drive = new Google_Client();
$drive->setClientId('XXX'); // HERE I WRITE MY Client ID
$drive->setClientSecret('XXX'); // HERE I WRITE MY Client Secret
$drive->setRedirectUri('urn:ietf:wg:oauth:2.0:oob');
$drive->setScopes(array('https://www.googleapis.com/auth/drive'));
$gdrive = new Google_DriveService($drive);
$url = $drive->createAuthUrl();
$authorizationCode = trim(fgets(STDIN));
$token = $drive->authenticate($authorizationCode);
?>
When I visit http://www.MYSERVER.com/script1.php I allow authorization and get the Auth code that I can write in a second script. Then I upload it to http://www.MYSERVER.com/script2.php, who looks like:
<?php
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_DriveService.php';
$drive = new Google_Client();
$drive->setClientId('X'); // HERE I WRITE MY Client ID
$drive->setClientSecret('X'); // HERE I WRITE MY Client Secret
$drive->setRedirectUri('urn:ietf:wg:oauth:2.0:oob');
$drive->setScopes(array('https://www.googleapis.com/auth/drive'));
$gdrive = new Google_DriveService($drive);
$_GET['code']= 'X/XXX'; // HERE I WRITE AUTH CODE RETRIEVED AFTER RUNNING REMOTE script.php
file_put_contents('token.json', $drive->authenticate());
$drive->setAccessToken(file_get_contents('token.json'));
$doc = new Google_DriveFile();
$doc->setTitle('Test Drive');
$doc->setDescription('Document');
$doc->setMimeType('text/plain');
$content = file_get_contents('drive.txt');
$output = $gdrive->files->insert($doc, array(
'data' => $content,
'mimeType' => 'text/plain',
));
print_r($output);
?>
Well, now the file drive.txt is uploaded on my Google Drive and structure of token.json file is a sort of:
{"access_token":"XXX","token_type":"Bearer","expires_in":3600,"refresh_token":"YYY","created":1365505148}
Now, as you can imagine I can call script2.php and upload file until a certain time. Finally, the point is: I don't want the token to expire, I don't want to allow authorization each time it expire (recalling script1.php): I need to call the script2.php periodically during the day, to upload my file automatically, without user interaction. So, what's the best way to automatically refresh the token forever in this context? Do I need another script? Can I add some code to script2.php? or modify the token.json file? And where can I read the time remaining before the token expire? Thanks!
You don't have to periodically ask for an access token. If you have a refresh_token, PHP client will automatically acquire a new access token for you.
In order to retrieve an refresh_token, you need to set access_type to "offline" and ask for offline access permissions:
$drive->setAccessType('offline');
Once you get a code,
$_GET['code']= 'X/XXX';
$drive->authenticate();
// persist refresh token encrypted
$refreshToken = $drive->getAccessToken()["refreshToken"];
For future requests, make sure that refreshed token is always set:
$tokens = $drive->getAccessToken();
$tokens["refreshToken"] = $refreshToken;
$drive->setAccessToken(tokens);
If you want a force access token refresh, you can do it by calling refreshToken:
$drive->refreshToken($refreshToken);
Beware, refresh_token will be returned only on the first $drive->authenticate(), you need to permanently store it. In order to get a new refresh_token, you need to revoke your existing token and start auth process again.
Offline access is explained in detail on Google's OAuth 2.0 documentation.
After messing a lot I got this to work. I am using one file/script to get the offline token and then a class to do stuff with the api:
require_once 'src/Google/autoload.php'; // load library
session_start();
$client = new Google_Client();
// Get your credentials from the console
$client->setApplicationName("Get Token");
$client->setClientId('...');
$client->setClientSecret('...');
$client->setRedirectUri('...'); // self redirect
$client->setScopes(array('https://www.googleapis.com/auth/drive.file'));
$client->setAccessType("offline");
$client->setApprovalPrompt('force');
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
$client->getAccessToken(["refreshToken"]);
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
return;
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if (isset($_REQUEST['logout'])) {
unset($_SESSION['token']);
$client->revokeToken();
}
?>
<!doctype html>
<html>
<head><meta charset="utf-8"></head>
<body>
<header><h1>Get Token</h1></header>
<?php
if ($client->getAccessToken()) {
$_SESSION['token'] = $client->getAccessToken();
$token = json_decode($_SESSION['token']);
echo "Access Token = " . $token->access_token . '<br/>';
echo "Refresh Token = " . $token->refresh_token . '<br/>';
echo "Token type = " . $token->token_type . '<br/>';
echo "Expires in = " . $token->expires_in . '<br/>';
echo "Created = " . $token->created . '<br/>';
echo "<a class='logout' href='?logout'>Logout</a>";
file_put_contents("token.txt",$token->refresh_token); // saving access token to file for future use
} else {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
?>
</body>
</html>
You can load refresh token from file and use it as necessary for offline access:
class gdrive{
function __construct(){
require_once 'src/Google/autoload.php';
$this->client = new Google_Client();
}
function initialize(){
echo "initializing class\n";
$client = $this->client;
// credentials from google console
$client->setClientId('...');
$client->setClientSecret('...');
$client->setRedirectUri('...');
$refreshToken = file_get_contents(__DIR__ . "/token.txt"); // load previously saved token
$client->refreshToken($refreshToken);
$tokens = $client->getAccessToken();
$client->setAccessToken($tokens);
$this->doSomething(); // go do something with the api
}
}
More here: https://github.com/yannisg/Google-Drive-Uploader-PHP