Why cant I get Data from the Google OAuth API through PHP? - php

I have a login script created which allows you to login through the Google API. Everything works fine and the redirect back to my website does also work.
Here is my script for the oauth callback:
<?php
require_once 'google-api-php-client-2.2.1/vendor/autoload.php';
session_start();
if (isset ($_GET["error"])) {
header('Location: #');
}
if (isset ($_GET["code"])) {
$client = new Google_Client();
$client->authenticate($_GET['code']);
$_SESSION['g_access_token'] = $client->getAccessToken();
$redirect = "http://".$_SERVER["HTTP_HOST"].$_SERVER["PHP_SELF"];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset ($_SESSION["g_access_token"])) {
$plus = new Google_Service_Plus($client);
$client->setAccesToken($_SESSION["g_access_token"]);
$me = $plus->people->get('me');
$_SESSION["unid"] = $me["id"];
$_SESSION["g_name"] = $me["displayName"];
$_SESSION["email"] = $me["emails"][0]["value"];
$_SESSION["g_profile_image_url"] = $me["image"]["url"];
$_SESSION["g_cover_image_url"] = $me["cover"]["coverPhoto"]["url"];
$_SESSION["g_profile_url"] = $me["url"];
}
?>
I dont get any error, but the session variables are still undefined. Where is the problem?
I just read and watched lots of tutorials, but still dont get it. Maybe somebody can help me here!
Thank you :)
EDIT
I just debugged my code and now I know that the Session Variable 'g_access_token' is empty after the login. So the main reason why it doesnt work should be the authentication. But I still dont know how to solve that...

I've just come from dealing successfully with Google OAuth API for PHP. So far, your code doesn't seem broke. Anyhow, it'd be nice to check your config file from which you get the class new Google_Client().
As that file is not posted in your question, i recommend you to follow this one, and call it through require_once to whenever you need it:
<?php
session_start();
require_once "GoogleAPI/vendor/autoload.php";
$gClient = new Google_Client();
$gClient->setClientId("your_client_id_comes_here");
$gClient->setClientSecret("your_client_secret");
$gClient->setApplicationName("CPI Login Tutorial");
$gClient->setRedirectUri("your_authorized_uri.php");
//addScope sets the permissions you'll have in your app, whether it is only for displaying them or to handle as you desire (e.g.: store account's information, such as email givenName and so on, into your own db
$gClient->addScope("https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/plus.me");
?>
Also, don't you forget to enable the Google + API in your Google console. Finally, check that in your credentials, the "Authorized redirect URIs" contains the redirect uri you want the google api to callback once the user is authenticated.

Related

Google PHP API not returning refresh token

I am working on a web application that, among other things, reads the gmail of a signed in user. I am using the Google PHP library to handle authentication, and I am able to fetch emails without problems. The problem is that the access token expires after 1 hour. The documentation indicates that you should get a refresh token with the initial authorization, but when I call $client->getRefreshToken(), it returns null.
I understand that the refresh token is only returned the first time that a user signs in. While testing this, I revoked the authorization on the account, and then tried again, but it still does not give me a refresh token. What am I doing wrong?
Edit: I had a friend sign in with his personal Google account, which has never been used on the site, and still, no refresh token was given.
Source code:
Login.php: The first page
<?php
session_start();
require_once 'vendor/autoload.php';
$force=(isset($_GET['force'])&&$_GET['force']='true');
if(!isset($_SESSION['google_token'])||force)
{
$client=new Google_Client();
$client->setAuthConfig('/path/to/client_secret.json');
$client->addScope('https://www.googleapis.com/auth/gmail.readonly');
$client->addScope('https://www.googleapis.com/auth/userinfo.email');
$client->addScope('https://www.googleapis.com/auth/userinfo.profile');
$client->setState('offline'); //I realized that the mistake is here, see my answer below.
$client->setApprovalPrompt('force');
if($force)
$client->setPrompt('consent');
$client->setRedirectUri('https://example.com/doLogin.php');
$auth_url=$client->createAuthUrl();
header("Location: " . filter_var($auth_url, FILTER_SANITIZE_URL));
die();
}
header('location: /index.php');
die();
doLogin.php: The Google Oauth page redirects here.
<?php
session_start();
require_once 'vendor/autoload.php';
if(isset($_GET['error']))
{
session_unset();
header('location: /error.php?error='.urlencode('You must be signed into Google to use this program.'));
die();
}
$client=new Google_Client();
$client->setAuthConfig('/path/to/client_secret.json');
$client->setRedirectUri('https://example.com/doLogin.php');
$client->setAccessType('offline');
$client->authenticate($_GET['code']);
$access_token=$client->getAccessToken();
$refresh_token=$client->getRefreshToken();
$service=new Google_Service_Oauth2($client);
$email=$service->userinfo->get()['email'];
$_SESSION['email']=strtolower($email);
$_SESSION['access_token']=$access_token;
$_SESSION['refresh_token']=$refresh_token;
header('Location: /index.php');
die();
?>
OK, so after looking around, and poking through the raw http, I found my mistake. I was calling $client->setState('offline'); instead of $client->setAccessType('offline'); I fixed that, and now I am receiving the refresh token when I should.

Google Analytics API blank screen when querying accounts?

I am novice to Google Analytics Api. I just started working on a small project where I want to pull data from the API and display it on each user’s Dashboard, using one single Google Analytics Account. I tried to follow the tutorial provided by google and made adjustments where required due to update to the library.
I am working on a codeigniter based platform and I was able to create a Google Client Object and also to make use of a refresh token which is saved in the database. I use the refresh token in order to have the data available on the dashboard without having to manually login every time.
The access token is there every time when I am logged in, and I can use it to set the client access token and create a Google Service Analytics object ($service = new Google_Service_Analytics($client);). I am printing the service and I can see the client id, client secret, etc and the access token being passed to it; but other like Google_Service_Analytics_DataGa_Resource Object are empty ( I do not know if they should be like that or not at this particular step ?).
When I am trying to request the user accounts
$accounts = $analytics->management_accounts->listManagementAccounts();,
I get a blank screen and my view is not being rendered.
I could not find such a problem being encountered before, so I am a bit confused why is happening. I do not get any error messages or anything that might point me to the cause of it or the right direction.
Note: I did managed to make it work using the same credentials trough JavaScript, but in this case it is not what I am looking for. I was able to retrieve data, display data in charts,etc using JS. I am new to making posts, so if anything is required from my part in order for you to have a better idea of what is going on, please do let me know.
I would greatly appreciate it I could get any indication to why that might be happening, or anything that would put me on the right path.
Codeigniter controller Class as follows
// Step 1 - Load PHP Client Libraries
require_once APPPATH.'libraries/Google/Client.php';
require_once APPPATH.'libraries/Google/Analytics.php';
class GoogleTest extends CI_Controller {
public function index(){
$this->load->helper(array('url','form'));
$this->load->model('googleapi_model'); //used to get the refresh token
// Step 2 - Start a session to persist credentials
session_start();
// Step 3 - Create and configure a new client object
$client = new Google_Client();
$client->setApplicationName("API Project");
// Insert client id, api key, client secret, project scope and redirect uri
$client->setDeveloperKey("***************");
$client->setClientId('********************');
$client->setClientSecret('******************');
$client->setRedirectUri('****************');
$client->setScopes(array('https://www.googleapis.com/auth/analytics.readonly'));
// Check if refresh token exists, it is used to login users automatically & it is being generated only once when you login the first time from the created
// google analytics app, this will take precedence to Step 4 or 6 below ;
if(count($this->googleapi_model->getGoogleRefreshToken()) > 0){
$db_refresh_token = $this->googleapi_model->getGoogleRefreshToken();
$client->refreshToken($db_refresh_token[0]->refreshtoken);
$_SESSION['token'] = $client->getAccessToken();
}else{
if ($client->getAccessToken()) {
$token = $client->getAccessToken();
$authObj = json_decode($token);
$refreshToken = $authObj->refresh_token;
if(isset($refreshToken) && $refreshToken != null){
$this->googleapi_model->insertGoogleRefreshToken($refreshToken);
}
}
}
//Step 4 - Handle authorization flow from the server
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 5 - Retrieve and use stored credentials
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
// Stept 6 - Either prompt the user to login or run the demo
if(!$client->getAccessToken()){
$authUrl = $client->createAuthUrl();
$this->data['auth'] = $authUrl;
}else{ //Create analytics service object
echo 'authenticated';
$analytics = new Google_Service_Analytics($client);
//TILL HERE MY CODE WORKS FINE, NO ERRORS, VIEW BEING RENDERED
$accounts = $analytics ->management_accountSummaries->listManagementAccountSummaries();
// $accounts = $analytics->management_accounts->listManagementAccounts();
echo '<pre>';
print_r($analytics);
echo '</pre>';
}
$this->data['content'] = '/public/dashboard/google_test';
$this->load->view('template/template', $this->data);
}
Make sure you're logged into the google account that API app is in.
And that you have clicked 'connect'.
Then run the script.
Also turn on error reporting (including notices)

Unauthorized 401 on Google+ API moments.insert with PHP

I want to create a small bot, which can push G+ moments to G+ page under certain conditions. Want to try it with PHP. So I have: registered web app in Google Console, Google+ API turned on, small PHP-script on my Apache server and 401 Unathorized in result. I'm using google-api-php-client from https://github.com/google/google-api-php-client
I've searched answer through the Internet, but nothing've found. Everywhere everyone have had their own happy end and all worked, but I've try all of it - and only 401 came to me.
My script:
<?
header("Content-Type: text/html; charset=utf-8");
session_start();
ini_set("display_errors", 1);
require_once 'Google/Client.php';
require_once 'Google/Service/Plus.php';
$client = new Google_Client();
$client->setClientId("MY_CLIENT_ID");
$client->setClientSecret("MY_CLIENT_SECRET");
$client->setRedirectUri("REDIRECT_URL");
$client->setAccessType('offline');
$client->addScope("https://www.googleapis.com/auth/plus.login");
$client->addScope("https://www.googleapis.com/auth/plus.me");
$client->addScope("https://www.googleapis.com/auth/userinfo.profile");
$client->addScope("https://www.googleapis.com/auth/userinfo.email");
$requestVisibleActions = array('http://schemas.google.com/AddActivity');
$client->setRequestVisibleActions($requestVisibleActions);
if (!isset($_GET['code'])) {
if (isset($_SESSION['access_token'])) {
$client->setAccessToken($_SESSION['access_token']);
$moment_body = new Google_Service_Plus_Moment();
$plus = new Google_Service_Plus($client);
$moment_body->setType("http://schemas.google.com/AddActivity");
$item_scope = new Google_Service_Plus_ItemScope();
$item_scope->setId("target-id-214wdefsadf1");
$item_scope->setType("http://schemas.google.com/AddActivity");
$item_scope->setName("The Google+ Platform");
$item_scope->setDescription("A page that describes just how awesome Google+ is!");
$item_scope->setImage("https://developers.google.com/+/plugins/snippet/examples/thing.png");
$moment_body->setTarget($item_scope);
$momentResult = $plus->moments->insert('me', 'vault', $moment_body);
} else {
$authUrl = $client->createAuthUrl();
header("Location: ".$authUrl);
exit;
}
} else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
header("Location: REDIRECT_URL");
exit;
}
So script succefully requests all needed access accordingly to scopes registered in client, gets a token, writes it into session, but when it try to insert new moment it gets 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 /var/www/rico/Google/Http/REST.php:79
What is wrong? And I've try some solutions placed here, on stackoveflow, but they didn't help. I also checked my authURL - it seems OK, with correct request_visible_actions and other... I don't know what is wrong...
You may be missing a few things. Maybe your example assumes you are putting the real values for some of these you have set. However you will want ApplicationName and DeveloperKey set. Many api calls will return not authorized if you don't have the developer key set for sure.
$client->setApplicationName($plApp->authenticationData->applicationName);
$client->setDeveloperKey($authData->apiKey);
I presume you are actually setting these below. Return url must match that which was set for the application on the google developer site for the specific application
$client->setClientId($authData->clientId);
$client->setClientSecret($authData->clientSecret);
$client->setRedirectUri($returnUrl);

how to grab gmail contact list after user gets authenticated with oauth2

After getting user authenticated with oauth2, i got the token.
so how that get request should be to retrieve user's gmail contact list in php ?
here is the code for oauth2
session_start();
require_once 'src/apiClient.php';
$client = new apiClient();
$client->setClientId('CLIENTID');
$client->setClientSecret('CLIENTSECRET');
$client->setRedirectUri('URI');
$client->setApplicationName("NAME");
$client->setScopes("http://www.google.com/m8/feeds/");
if (isset($_SESSION['access_token'])) {
$client->setAccessToken($_SESSION['access_token']);
} else {
$client->setAccessToken($client->authenticate());
}
$_SESSION['access_token'] = $client->getAccessToken();
print($_SESSION['access_token']);
then how can i get contact list of user ?
Thank you
You were reading the right document. But refer the section Client Libraries and Sample Code for sample code.
Also, check the link http://gdatatips.blogspot.com/2008/11/2-legged-oauth-in-php.html
I can see that the example uses Google contacts list API retrieval.
You ware looking at the wrong doco. Try this instead http://code.google.com/apis/contacts/docs/3.0/developers_guide.html
here is the url that you are looking for https://www.google.com/m8/feeds/contacts/userEmail/full
You can get an idea by using this:
https://code.google.com/oauthplayground/
choose contact to see one by one steps. Just pass data from one URL to other.
And refer this blog...
http://anandafit.info/2011/03/08/google-contact-list-reader-in-php-google-oauth/

Persistent Google OpenID+OAuth?

I'm working on a web app that will require somewhat frequent access to Google Data APIs, so I decided to go with the "OAuth with Federated Login (Hybrid Protocol)" method for users to log into the app. I got the http://googlecodesamples.com/hybrid/ working (after some tweaks for PHP 5.3 compatibility), and am able to get an Access Token. What's the next step? How do I use this access token?
It seems like I'll need to create a local session for the user to browse the rest of the app. Will this need to be completely independent of the Google login, or how would you handle that?
Relevant: this application also needs a REST API, for which I was planning to use OAuth. Any recommendation on how to tie this in with authentication for the actual app?
I am using the PHP LightOpenID library (see on gitorious) for that. It handles all the authentication flow for us. You don't need to bother about token and stuff.
Here the page where I display the "Login with Google" link :
<?php
require_once 'openid.php';
$openid = new LightOpenID;
$openid->identity = 'https://www.google.com/accounts/o8/id';
$openid->required = array('contact/email');
$openid->returnUrl = 'http://my-website.com/landing-login.php'
?>
Login with Google
When the click on the link, a Google page will appear ask him to authenticate and/or authorize you to retrieve his email.
Then he will be redirect to the landing page $openid->returnUrl. The code for that page should be :
<?php
require_once 'openid.php';
$openid = new LightOpenID;
if ($openid->mode) {
if ($openid->mode == 'cancel') {
// User has canceled authentication
} elseif($openid->validate()) {
// Yeah !
$data = $openid->getAttributes();
$email = $data['contact/email'];
} else {
// The user has not logged in via Google
}
} else {
// The user does not come from the link of the first page
}
?>
If you want to retrieve more info from the user, you have to add them to $openid->required in the first page. For instance :
$openid->required = array(
'contact/email',
'namePerson/first',
'namePerson/last'
);
will let you, if the user accepts it, to get his first and last names as well in the second page :
$name = $data['namePerson/first'] . " " . $data['namePerson/last'];
Then, for the Oauth part, you can follow the instructions of this LightOpenID issue.

Categories