I copied this from the test folder included in the php sdk. It redirects to google for authentication as expected but when calling $oauth2->userinfo->get() it just hangs there. The cloud console said the error was 400 but I don't see what I could be doing wrong.
I updated the setting as per what is on my page. I've been searching for an answer for 2 hours. Please help :(
/* OAuth settings */
$clientID = 'blahblah.apps.googleusercontent.com';
$clientSecret = 'secret';
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$developerKey = 'key';
$client = new Google_Client();
$client->setApplicationName("Study-Corner");
$client->setClientId($clientID);
$client->setClientSecret($clientSecret);
$client->setRedirectUri($redirect);
$client->setDeveloperKey($developerKey);
$oauth2 = new Google_Oauth2Service($client);
if(isset($_GET['code'])) {
$client->authenticate($_GET['code']);
// get the access token
$_SESSION['token'] = $client->getAccessToken();
// redirect back
header('Location: '. filter_var($redirect, FILTER_SANITIZE_URL));
return;
}
if(isset($_SESSION['token'])) {
// set the access token
$client->setAccessToken($_SESSION['token']);
}
/* check if we have access */
if($client->getAccessToken()) {
$user = $oauth2->userinfo->get();
// These fields are currently filtered through the PHP sanitize filters.
// See http://www.php.net/manual/en/filter.filters.sanitize.php
$email = filter_var($user['email'], FILTER_SANITIZE_EMAIL);
$img = filter_var($user['picture'], FILTER_VALIDATE_URL);
print $email;
// The access token may have been updated lazily.
$_SESSION['token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
header("Location: ".$authUrl);
die;
}
Add $client->setScopes('profile); to your client details.
Related
I am logging a user using Google login. I have included all the necessary files needed for Google login. I have created a PHP script for log-in. I have all my authentication and redirection info in place. However, I do not understand why am I not getting email field which I am getting from googleClient in my session. Please help.
Here is my code:
<?php
$google_client_id = '#########.apps.googleusercontent.com';
$google_client_secret = 'xxxxxxxxxxxxxxxxxxx';
$google_redirect_url = 'http://localhost/project/profile.php';
$google_developer_key = '';
//include google api files
require_once '../src/Google_Client.php';
require_once '../src/contrib/Google_Oauth2Service.php';
session_start();
$gClient = new Google_Client();
$gClient->setClientId($google_client_id);
$gClient->setClientSecret($google_client_secret);
$gClient->setRedirectUri($google_redirect_url);
$google_oauthV2 = new Google_Oauth2Service($gClient);
if (isset($_REQUEST['reset']))
{
unset($_SESSION['token']);
$gClient->revokeToken();
header('Location: ' . filter_var($google_redirect_url, FILTER_SANITIZE_URL));
}
if (isset($_GET['code']))
{
$gClient->authenticate($_GET['code']);
$_SESSION['token'] = $gClient->getAccessToken();
header('Location: ' . filter_var($google_redirect_url, FILTER_SANITIZE_URL));
return;
}
if (isset($_SESSION['token']))
{
$gClient->setAccessToken($_SESSION['token']);
}
if ($gClient->getAccessToken())
{
//Get user details if user is logged in
$user = $google_oauthV2->userinfo->get();
$user_id = $user['id'];
$user_name = filter_var($user['name'], FILTER_SANITIZE_SPECIAL_CHARS);
$email = filter_var($user['email'], FILTER_SANITIZE_EMAIL);
$profile_url = filter_var($user['link'], FILTER_VALIDATE_URL);
$profile_image_url = filter_var($user['picture'], FILTER_VALIDATE_URL);
$personMarkup = "$email<div><img src='$profile_image_url?sz=50'></div>";
$_SESSION['token'] = $gClient->getAccessToken();
$_SESSION['email'] = $email;
}
else
{
//get google login url
$authUrl = $gClient->createAuthUrl();
}
?>
My profile.php looks like this -
It results in -
Notice: Undefined index: email on line 4
After this script runs, the control jumps to the next page where it says that email is not found in session. Should I create a new Google_Client()? Whats the proper way to do this series of interaction after login?
First of all it will work on localhost, no problem. Because I have just created google and facebook login and it works fine.
you need to add Google ClientID and Client secret key from the console developer google where you have created web app and ouath key.
In main Login page you can redirect to another page...
/*! \brief Configure the client object
* Exchange authorization code for refresh and access tokens
*/
if (isset($_GET['code'])) {
$gClient->authenticate($_GET['code']);
$_SESSION['token'] = $gClient->getAccessToken(); /**< retrieve the access token with the getAccessToken method */
header('Location: ' . filter_var($redirectURL, FILTER_SANITIZE_URL)); /**< Redirect the user to $auth_url: */
}
if (isset($_SESSION['token'])) {
$gClient->setAccessToken($_SESSION['token']); /**< apply an access token to a new Google_Client object */
}
$authUrl = $gClient->createAuthUrl(); /**< Generate a URL to request access from Google's OAuth 2.0 server */
Try this..
!(set($_GET['code'])) {
$gClient->authenticate($_GET['code']);
$_SESSION['token'] = $gClient->getAccessToken(); /**< retrieve the access token with the getAccessToken method */
header('Location: ' . filter_var($redirectURL, FILTER_SANITIZE_URL)); /**< Redirect the user to $auth_url: */ }
if (isset($_SESSION['token'])) {
$gClient->setAccessToken($_SESSION['token']); /**< apply an access token to a new Google_Client object */
})
I am trying to retrieve all my contacts using Google Contact API. For this I used Oauth2.0 authentication and Google Contact API for PHP.
But i am getting this error:
"Fatal error: Class 'Google_Http_Request' not found in"
could not get the reason why. I even used Google_HttpRequest but error remains the same but this time it is for "Google_HttpRequest".
Code used is as follows, can some one help because for this this there no help is available on internet
<?php
//require_once 'C:/xampp/htdocs/google-api-php-client-master/src/Google/Client.php';
require_once 'C:/xampp/htdocs/google-api-php-client-master/vendor/autoload.php';// or wherever autoload.php is located
session_start();
//Declare your Google Client ID, Google Client secret and Google redirect uri in php variables
$google_client_id = 'xxx-yyy.apps.googleusercontent.com';
$google_client_secret = 'xxxx';
$google_redirect_uri = 'https://localhost:4433/xxx.php';
$client = new Google_Client();
$client -> setApplicationName('My application name');
$client -> setClientid($google_client_id);
$client -> setClientSecret($google_client_secret);
$client -> setRedirectUri($google_redirect_uri);
$client -> setAccessType('online');
$client->setApplicationName('Google Contacts PHP Sample');
$client->setScopes("http://www.google.com/m8/feeds/");
///if (isset($_GET['code'])) {
/// $client->authenticate($_GET['code']);
/// $auth_code = $_GET["code"];
/// $_SESSION['google_code'] = $auth_code;
/// header('Location: ' . $google_redirect_uri);
///}
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if (isset($_REQUEST['logout'])) {
unset($_SESSION['token']);
$client->revokeToken();
}
if ($client->getAccessToken()) {
//$req = new Google_Http_Request("https://www.google.com/m8/feeds/contacts/default/full", 'GET', null, null);
$req = new Google_Http_Request("https://www.google.com/m8/feeds/contacts/default/full");
$val = $client->getIo()->authenticatedRequest($req);
// The contacts api only returns XML responses.
$response = json_encode(simplexml_load_string($val->getResponseBody()));
print "<pre>" . print_r(json_decode($response, true), true) . "</pre>";
// The access token may have been updated lazily.
$_SESSION['token'] = $client->getAccessToken();
} else {
$auth = $client->createAuthUrl();
}
if (isset($auth)) {
print "<a class=login href='$auth'>Connect Me!</a>";
} else {
print "<a class=logout href='?logout'>Logout</a>";
}
You are trying to mix things that cant be mixed.
The current Google php client library which you are using only supports discovery service APIs. Which are the new APIs that return Json.
The google contacts API is an older Gdata api which returns XML. the two do not speak the same language. I haven't tried it but the old GData client library can be found here.
<?php
session_start();
require_once realpath(dirname(__FILE__) . '/Google/src/Google/autoload.php');
/************************************************
ATTENTION: Fill in these values! Make sure
the redirect URI is to this page, e.g:
http://localhost:8080/user-example.php
************************************************/
$client_id = 'xxxxx-1l76cd2vi4ik5oqm5s20nj965riu4hum.apps.googleusercontent.com';
$client_secret = 'secret';
$redirect_uri = 'http://www.audit.polydevs.co.uk/oauth2callback.php?login';
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->setScopes('email');
/************************************************
If we're logging out we just need to clear our
local access token in this case
************************************************/
if (isset($_REQUEST['logout'])) {
unset($_SESSION['access_token']);
header("Location: login.php");
}
if (isset($_REQUEST['logoutInvalid'])) {
unset($_SESSION['access_token']);
header("Location: login.php?invalid");
}
/************************************************
If we have a code back from the OAuth 2.0 flow,
we need to exchange that with the authenticate()
function. We store the resultant access token
bundle in the session, and redirect to ourself.
************************************************/
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
/************************************************
If we have an access token, we can make
requests, else we generate an authentication URL.
************************************************/
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
} else {
$authUrl = $client->createAuthUrl();
}
/************************************************
If we're signed in we can go ahead and retrieve
the ID token, which is part of the bundle of
data that is exchange in the authenticate step
- we only need to do a network call if we have
to retrieve the Google certificate to verify it,
and that can be cached.
************************************************/
if ($client->getAccessToken()) {
$_SESSION['access_token'] = $client->getAccessToken();
$token_data = $client->verifyIdToken()->getAttributes();
}
if($client->isAccessTokenExpired()) {
echo 'Access Token Expired'; // Debug
$client->authenticate;
$newAccessToken = json_decode($client->getAccessToken());
$client->refreshToken($newAccessToken->refresh_token);
}
if (strpos($client_id, "googleusercontent") == false) {
echo missingClientSecretsWarning();
exit;
}
if (isset($_REQUEST['login'])) {
if (isset($authUrl)) {
header('Location:'.$authUrl);
} else {
require_once('func/connect.php');
$query = "SELECT * FROM users WHERE email = ?";
$stmt = $db->prepare($query);
$stmt->bindValue(1, $token_data['payload']['email']);
$stmt->execute();
$count = $stmt->rowCount();
if ($count > 0) {
header('Location: index.php');
} else {
$plus = new Google_Service_Plus( $client );
$me = $plus->people->get('me');
$query = "INSERT INTO users (name,email,role) VALUES(?,?,?)";
$stmt = $db->prepare($query);
$stmt->bindValue(1, $me['displayName']);
$stmt->bindValue(2, $token_data['payload']['email']);
$stmt->bindValue(3, 'regular');
$stmt->execute();
header('Location: index.php');
}
}
}
Specifically here
if($client->isAccessTokenExpired()) {
echo 'Access Token Expired'; // Debug
$client->authenticate;
$newAccessToken = json_decode($client->getAccessToken());
$client->refreshToken($newAccessToken->refresh_token);
}
Once my token expires, I cannot logout nor access any of the webpages as they require to have a valid token..
nor can i login, as that requires it too!
Or alternatively, can I just disable it!
EDIT
I'm very sorry, I'm tired and assuming everyone knows what I'm talking about.. The issue is that when the access token expires, I can either unset the $_SESSION['access_token'] and force relogging in ( major problem ) or have a way of just refreshing / disabling the token/expire so it won't impede on any ongoing processes for the user.
I would recommend reading a basic guide about OAuth so you can get the general idea.
Basically the server and the client go through a series of steps to prove that they are who they say they are. Once this has been completed the server will issue a short lived access_token and a refresh_token.
You can then use this access_token in all Api requests. However this access_token has a limited lifetime. When it expires you must give the refresh_token to the server and it will issue another access_token
To do this with the Google Api PHP library you use this code
//$client is the GApi Client
if($client->isAccessTokenExpired()) {
echo 'Access Token Expired'; // Debug
$client->refreshToken('your_refresh_token');
}
Using code below I successfully received a token and using this token also get user detail, but when I try to post/insert moment in user wall I see the following error message
Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling POST https:--www.googleapis.com/plus/v1/people/me/moments/vault: (401) Unauthorized' in $_SESSION['access_token_gp']
I got user token when user login using my site in login page I ask for below permission
$client->addScope("email");
$client->addScope("https://www.googleapis.com/auth/plus.stream.write");
$client->addScope("https://www.googleapis.com/auth/plus.login");
If I print_r($tokenInfo); you will see all scope which I ask at login time.
The full code:
session_start();
require_once realpath(dirname(__FILE__) . '/google-api-php-client-master/autoload.php');
$client_id = 'my_client_id';
$client_secret = 'my_secret_key';
$redirect_uri = 'my_redirect_url';
// code to post in google plus start here //
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
if (isset($_SESSION['access_token_gp'])) {
// Verify the token
$token = json_decode($_SESSION['access_token_gp']);
$reqUrl = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$token->access_token;
$req = new Google_Http_Request($reqUrl);
$tokenInfo = get_object_vars(json_decode($client->getAuth()->authenticatedRequest($req)->getResponseBody()));
if($tokenInfo['expires_in'] <= 0){
$client->authenticate($_SESSION['access_token_gp']);
$_SESSION['access_token_gp'] = $client->getAccessToken();
} else {
$client->setAccessToken($_SESSION['access_token_gp']);
}
$plusservicemoment = new Google_Service_Plus_Moment();
$plusservicemoment->setType("http://schemas.google.com/AddActivity");
$plusService = new Google_Service_Plus($client);
$item_scope = new Google_Service_Plus_ItemScope();
$item_scope->setId($tokenInfo['user_id']);
$item_scope->setType("http://schemas.google.com/AddActivity");
$item_scope->setName("The madexme Platform");
$item_scope->setDescription("A page that describes just how madexme is work!");
//$item_scope->setImage("full image path here");
$plusservicemoment->setTarget($item_scope);
$result = $plusService->moments->insert('me','vault',$plusservicemoment);
//print_r($result);
}
// code to post in google plus end here //
Make sure you have the latest client lib from GitHub. There is something wrong with your Oauth2 connection. This code is partially converted from my Google Google Calendar API tutorial. I don't have the power to test it right now. But this should be close. I will test it tonight.
<?php
require_once 'Google/Client.php';
require_once 'Google/Service/Plus.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$client->setDeveloperKey("AIzaSyBBH88dIQPjcl5nIG-n1mmuQ12J7HThDBE");
$client->setClientId('2046123799103-i6cjd1hkjntu5bkdkjj5cdnpcu4iju8p.apps.googleusercontent.com');
$client->setClientSecret('6s4YOx3upyJhtwnetovfK40e');
$client->setRedirectUri('http://localhost/google-api-php-client-samples/Calendar/oauth2Pure.php');
$client->setAccessType('offline'); // Gets us our refreshtoken
$client->setScopes(array(https://www.googleapis.com/auth/plus.login'));
//For loging out.
if (isset($_GET['logout'])) {
unset($_SESSION['token']);
}
// Step 2: The user accepted your access now you need to exchange it.
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
// Step 1: The user has not authenticated we give them a link to login
if (!isset($_SESSION['token'])) {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
// Step 3: We have access we can now create our service
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
print "<a class='logout' href='".$_SERVER['PHP_SELF']."?logout=1'>LogOut</a><br>";
$service = new Google_Service_Plus($client);
$moment = new Google_Moment();
$moment->setType('http://schemas.google.com/AddActivity');
$itemScope = new Google_ItemScope();
$itemScope->setUrl('https://developers.google.com/+/plugins/snippet/examples/thing');
$moment->setTarget($itemScope);
$plus->moments->insert('me', 'vault', $moment);
?>
Again I hope you understand that this is not going to show up on the users Google+ page / timeline.
I'm want to get google+ posts via PHP, but google requires my login via browser.
It's possible provide the account's authentication via PHP, allowing me to get the posts without login every time I want to get the posts?
The code is:
<?php
require_once 'src/Google_Client.php';
require_once 'src/contrib/Google_PlusService.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Google+ PHP Starter Application");
// Visit https://code.google.com/apis/console?api=plus to generate your
// client id, client secret, and to register your redirect uri.
$client->setClientId('clientid');
$client->setClientSecret('clientsecret');
$client->setRedirectUri('http://localhost/OLA/google+/simple.php/b.html');
$client->setDeveloperKey('apikey');
$plus = new Google_PlusService($client);
if (isset($_GET['logout'])) {
unset($_SESSION['token']);
}
if (isset($_GET['code'])) { // login stuff <-------
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
die("The session state did not match.");
}
$client->authenticate();
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()) {
//$me = $plus->people->get('me');
//print "Your Profile: <pre>" . print_r($me, true) . "</pre>";
$params = array('maxResults' => 100);
$activities = $plus->activities->listActivities('me', 'public', $params);
//print "Your Activities: <pre>" . print_r($activities, true) . "</pre>";
$params = array(
'orderBy' => 'recent',
'maxResults' => '20'//20
);
$q = "tag";
$results = $plus->activities->search($q, $params);
//code ....
// The access token may have been updated lazily.
$_SESSION['token'] = $client->getAccessToken();
} else {
// This is the part that logs me in via browser <------
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
?>
Yep, just call as you would and use the simple API access key - you can retrieve public information, but you will have to supply to long numeric ID for the user you're retrieving posts for rather than using the string 'me'. Take a look at the latest version of the library as well: https://github.com/google/google-api-php-client as well. You need to setup your client as you were doing, with an API key from a project which has the Google+ enabled on https://developers.google.com/console
$client = new Google_Client();
$client->setApplicationName("Post Fetcher");
$client->setDeveloperKey('PUT_YOUR_API_KEY_HERE_OR_IT_WONT_WORK');
$plus = new Google_Service_Plus($client);
$activities = $this->plus->activities
->listActivities("118051310819094153327", "public");