I know I'm not the only one having this problem, but untile now I wasn't able to find a solution. Please help!
I'm experimenting with the php google client api to use it in my site. But I cannot authorize my request using $client->authenticate(); my page gets stuck with this error:
PHP Fatal error: Uncaught exception 'Google_AuthException' with message 'Error fetching OAuth2 access token, message: 'invalid_request'' in /Users/****/Sites/googleApiClient/google-api-php-client/src/auth/Google_OAuth2.php:113 Stack trace:
#0 /Users/****/Sites/googleApiClient/google-api-php-client/src/Google_Client.php(131): Google_OAuth2->authenticate(Array, NULL)
#1 /Users/****/Sites/googleApiClient/index.php(90): Google_Client->authenticate()
#2 /Users/****/Sites/googleApiClient/index.php(124): init()
#3 {main}
thrown in /Users/Angelo/Sites/googleApiClient/google-api-php-client/src/auth/Google_OAuth2.php on line 113
Here is my code (sism_debug() is something I use to var_export to the console):
<?php
function sism_debug($var){
$result = var_export( $var, true );
$trace = debug_backtrace();
$level = 1;
@$file = $trace[$level]['file'];
@$line = $trace[$level]['line'];
@$object = $trace[$level]['object'];
if (is_object($object)) { $object = get_class($object); }
error_log("Line $line ".($object?"of object $object":"")."(in $file):\n$result");
}
function retrieveAllFiles($client) {
require_once "google-api-php-client/src/contrib/Google_DriveService.php";
$service = Google_DriveService($client);
$result = array();
$pageToken = NULL;
do {
try {
$parameters = array();
if ($pageToken) {
$parameters['pageToken'] = $pageToken;
}
$files = $service->files->listFiles($parameters);
$result = array_merge($result, $files->getItems());
$pageToken = $files->getNextPageToken();
} catch (Exception $e) {
error_log("An error occurred: " . $e->getMessage());
$pageToken = NULL;
}
} while ($pageToken);
return $result;
}
session_start();
global $access_token;
error_log("What's in the SESSION global?");
sism_debug(@$_SESSION['access_token']);
$access_token = @$_SESSION['access_token'] || false;
function init(){
// Richiama la libreria di Google
require_once 'google-api-php-client/src/Google_Client.php';
// Crea un oggetto per immagazzinare i dati inseriti nel form. Qui andrebbero usate le funzioni di sanitizzazione degli input di WP
$app_data = array();
@$app_data['client_ID'] = $_POST['client_ID'];
@$app_data['client_secret'] = $_POST['client_secret'];
@$app_data['scopes'] = explode("\n",trim($_POST['scopes']));
@$app_data['redirect_url'] = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
// Confronta i nuovi dati con quelli salvati nel database
if($_SESSION['app_data'] !== $app_data){
$_SESSION['app_data'] = $app_data; //Salva i dati nel database
}
$client = new Google_Client();
$client->setClientId($app_data['client_ID']);
$client->setClientSecret($app_data['client_secret']);
$client->setRedirectUri($app_data['redirect_url']);
$client->setScopes($app_data['scopes']);
$client->setAccessType('offline');
//Numero random di sicurezza. In WP si usa wp_nonce()
if(!isset($_SESSION['security']) OR $_SESSION['security'] == ""){
$_SESSION['security'] = md5(rand());
}
$state = $_SESSION['security'];
$client->setState($state);
$client->setApplicationName('Google Api Client');
error_log('Client Set!');
if (isset($_GET['code']) AND $_GET['state'] == $state AND (!isset($access_token) OR !$access_token)){
error_log('Code arrived!');
sism_debug($_GET);
error_log('Now authenticating...');
$result = $client->authenticate(); // Get stucked here!
sism_debug($result);
$access_token = $_SESSION['access_token'] = $client->getAccessToken();
sism_debug($access_token);
}
if (!isset($access_token) OR !$access_token){
error_log("Creating authUrl...");
$authUrl = $client->createAuthUrl();
sism_debug($authUrl);
header('Location: ' . $authUrl);
exit();
}
else{
// Se richiesto il logout cancellare i dati registrati
if (isset($_POST['logout']) AND $_POST['logout'] == "true") {
error_log('Logging out!');
$client->revokeToken();
session_destroy();
}
else{
error_log('Setting up access token...');
$client->setAccessToken($access_token);
}
}
if ($client->getAccessToken()) {
error_log('Fetching Results');
sism_debug(retrieveAllFiles($client));
}
}
//Controlla che la pagina sia stata chiamata tramite un Submit del form o redirect di google
if( (@isset($_POST['manual_submit']) AND @$_POST['manual_submit']) OR (@isset($_GET['code']) AND @$_GET['code'])){
error_log('Manual submit or google redirect! Initialiazing...');
init();
}
elseif (@isset($_POST['error'])){
error_log('Something got wrong...');
sism_debug($_POST['error']);
}
error_log('Rendering page...');
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>GoogleApiClient</title>
<style type="text/css">
.hidden {
display: none;
}
</style>
</head>
<body>
<h1>Google Api Client</h1>
<p>L'applicazione proverà ad accedere ai tuoi dati</p>
<a href="http://<?php echo $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] ?>">link alla pagina</a>
<form action="index.php" method="POST">
<p>
<label>Client ID</label><br>
<input type="text" name="client_ID"/>
</p>
<p>
<label>Client Secret</label><br>
<input type="text" name="client_secret"/>
</p>
<p>
<label>Scopes</label><br>
<textarea name="scopes"></textarea>
</p>
<input type="hidden" name="manual_submit" value="true"/>
<?php if(!isset($access_token) OR $access_token == ""){?>
<input type="submit" value="Autorizza"/>
<input type="hidden" name="auth_action" value="authorize"/>
<?php }
else{ ?>
<input type="submit" value="Revoca"/>
<input type="hidden" name="auth_action" value="logout"/>
<?php } ?>
</form>
<script src="http://code.jquery.com/jquery-2.0.0.min.js"></script>
<script type="application/x-javascript">
$(document).ready(function() {
$("input:text, textarea").each(function(){
$(this).val(localStorage[$(this).attr('name')]);
})
$("form").submit(function(){
console.log("form submit!");
$("input:text, textarea").each(function(){
localStorage[$(this).attr('name')] = $(this).val();
})
});
});
</script>
</body>
</html>
As you can see, this script allows you to set your credential up in the front end.
Here is the request when asking for the code:
client_ID:****.apps.googleusercontent.com
client_secret:****
scopes:https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive
manual_submit:true
auth_action:authorize
As I said, then it gets stuck on authentication, but I don't know which form the request has, since is managed by the google client api.
Any idea??
Thanks!