Fetch Google Calendar Events on PHP server after authenticating on iOS app - php

Okay so here's what I want to do...
user authorized the app on iPhone with read/write access to Google calendar
I get an auth token of some kind from Google
Pass on the token to my PHP server and save it in database
Use the token to regularly check on Google events and store them in server's database
Send the Google events data as json to the app
I want to implement the fetching of Google events on server, so that I can build additional functionality around them like sending remote push notifications.
I am stuck at the part of getting auth token and saving it on server and using it to fetch events from Google's calendar api, having not able to find the resources for same. Can somebody throw some light on this.
UPDATE
I have been able to successfully implement the scenario till step 3.
I get the auth token and refresh token from Google and save it in database. Now using the Google API php client, I am trying to connect to Google's calendar API using the access token that I got earlier. I am using the following code...
require_once(APPPATH . "libraries/Google/Google_Client.php");
require_once(APPPATH . "libraries/Google/contrib/Google_CalendarService.php");
$client = new Google_Client();
$client->setAccessToken($google_access_token);
$calendar = new Google_CalendarService($client);
$calendarList = $calendar->calendarList->listCalendarList();
echo print_r($calendarList, true);
But now I get this error...
PHP Fatal error: Uncaught exception 'Google_AuthException' with
message 'Could not json decode the token' in
/myserver/application/libraries/Google/auth/Google_OAuth2.php:162
Stack trace:
/myserver/application/libraries/Google/Google_Client.php(170): Google_OAuth2->setAccessToken('a_token...')
I understand that I am directly trying to set the access token in Google client api without specifying any redirect url or other params normally used when the user authorizes the access to Google calendars on server itself. Is this supposed to work like I am trying to?
UPDATE 2
Upon some further digging, I found out that directly setting the access token using setAccessToken does not work as Google client for API expects a JSON encoded string in the setAccessToken method. After some tweaks I changed my code to following....
require_once(APPPATH . "libraries/Google/Google_Client.php");
require_once(APPPATH . "libraries/Google/contrib/Google_CalendarService.php");
$client = new Google_Client();
$client->setAccessType('offline');
$client->refreshToken($google_refresh_token);
$newToken = $client->getAccessToken();
$client->setAccessToken($newToken);
$calendar = new Google_CalendarService($client);
$calendarList = $calendar->calendarList->listCalendarList();
echo print_r($calendarList, true);
Now the error that I am getting is that of an invalid_request.
Error refreshing the OAuth2 token, message: '{"error" : "invalid_request"}'

Finally I am able to answer my own question. Hope this helps someone else.
Step 1 & 2. I got the Google OAuth protocol working in my iOS App following the instructions in this excellent tutorial on mobiletuts.
Step 3. I saved the access token and refresh token in database on my web server.
Step 4. Using the refresh token I got from iOS App I connected to the Google calendar API with this code...
require_once(APPPATH . "libraries/Google/Google_Client.php");
require_once(APPPATH . "libraries/Google/contrib/Google_CalendarService.php");
/* setup google client object */
$client = new Google_Client();
$client->setClientId(GOOGLE_CLIENT_ID);
/* refresh access token */
$client->refreshToken($google_refresh_token);
$newToken = $client->getAccessToken();
$client->setAccessToken($newToken);
/* get google calendars list */
$calendar = new Google_CalendarService($client);
$calendarList = $calendar->calendarList->listCalendarList();
echo print_r($calendarList, true);

Related

Storing the Google OAuth Authorization Token in Database

I am building a portal where multiple users can log in to their multiple Gmail accounts. I have successfully retrieved the token value, However, I want to store that in my database but I am unable to store it.
Below is the code I am using:
function mInititalize(){
$client = new Google_Client();
$client->addScope('https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://mail.google.com/');
$client->setClientId(Config('gmail.client_id'));
$client->setClientSecret(Config('gmail.client_secret'));
$client->setRedirectUri('http://localhost:81'.Config('gmail.redirect_url'));
$loginURL = $client->createAuthUrl();
return redirect($loginURL);
}
After Redirection or user login
function mGetToken(){
$token = $client->fetchAccessTokenWithAuthCode( 'code'); // here i get the 'code' from login URL
I pass this code to get token I successfully get token
$oAuth = new Google_Service_Oauth2( $client);
$userData = $oAuth->userinfo_v2_me->get(); // get current user detail
}
I want to store $token value in database, but I am getting error message
>Serialization of 'Closure' is not allowed
Please anyone help me to solve this issue. Thanks.
I would suggest storing OAuth credential information for the Google API, not in your database, but through the API itself. If you're intending to use it any authentication manner, you'll run into problems, as the docs state:
Access tokens periodically expire and become invalid credentials for a related API request. Google Identity Platform: Using OAuth 2.0 for Web Server Applications
But, the same docs also show a way that you can set or retrieve the token natively within the API. Since it's data relating to google's auth'ing process, and since it might go stale if you store it, it seems best to just let them handle it and work with the API. The same source:
If you need to apply an access token to a new Google_Client object—for example, if you stored the access token in a user session—use the setAccessToken method:
$client->setAccessToken($access_token);
$client->getAccessToken();

Google_Auth_Exception: Error refreshing the OAuth2 token

I am trying to fetch user's data from google plus using PHP.
I'm using below tutorial
https://www.youtube.com/watch?v=-65R420rIUA
Situation:
User login into my app android using google plus button i fetch the access token using googleSignInResult.googleSignInAccount.getIdToken()
I send this token to my server which runs php to fetch users data using google php client (as described in the video)
below is my code
try{
$gClient = new Google_Client();
$gClient->setApplicationName('pixyfi');
$gClient->setClientId($config['google']['appid']);
$gClient->setClientSecret($config['google']['secret']);
$token = json_encode(array("access_token"=>$lptoken,"refresh_token"=>$lptoken,"token_type"=>"Bearer","expires_in"=>3600,"id_token"=>$lptoken,"created"=>1320790426));
$gClient->setAccessToken($token);
$gClient->addScope(Google_Service_Plus::PLUS_ME);
$plus = new Google_Service_Plus($gClient);
$gpUserProfile = $plus->people->get('me');
echo "User Fetched as:".$gpUserProfile['id'];
}
catch(Google_Auth_Exception $x){
echo "Error:".$x;
}
But i am getting error:
Error:Google_Auth_Exception: Error refreshing the OAuth2 token, message: '{
"error" : "invalid_client"
}' in /var/www/html/api/auth/vendor/google/apiclient/src/Google/Auth/OAuth2.php:364
Could you please let me know what mistake i am making here?
this is some of my code which handles token thing. Implement this logic and let me know if you are still getting errors.
$row is is fetched from database and contains token information
$client->setAccessToken($row['token']);
if(time()>$row['created']+$row['expires_in'])
{
$client->refreshToken($row['refresh_token']);
$token=$client->getAccessToken();
DB::Query("-----UPDATE DB TOKEN INFO-------");
$client->setAccessToken($token);
}

Google PHP SDK - not getting refresh token

I am trying to get a refresh token for the Google API's, using the PHP SDK. I am authenticating the user with Javascript, retrieving a code, and exchanging it for an access_token server side, but this doesn't grant me an access token. What am I doing wrong? Here is the code I use:
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->addScope('https://www.googleapis.com/auth/plus.me');
$client->addScope('https://www.google.com/m8/feeds');
$client->setRedirectUri('postmessage');
$client->setAccessType('offline');
if (isset($_REQUEST['code'])) {
$client->authenticate($_REQUEST['code']);
if ($client->getAccessToken()) {
$_SESSION['access_token'] = $client->getAccessToken();
$token_data = $client->verifyIdToken()->getAttributes();
$result['data']=$token_data;
$result['access_token']=json_decode($_SESSION['access_token']);
}
}
debug($result); //my own function, var_dumps the content of an array
Here is the result of the array:
$result['access_token'] contains:
access_token: TOKEN
created: 1434380576
expires_in: 3594
id_token: IDTOKEN
token_type:"Bearer"
If I am not mistaken the first access token should also contain the refresh token, what am I doing wrong?
First check the settings in the developer console of Google to see if your RedirectUri is the same and that the API is activated (although if you already got that .json, then I assume it is.
You have to go through the Google Auth Prompt Screen at least 1 time to get a refresh token in your .json, and if your RedirectUri is taking you nowhere, you won't be able to get your refresh token or even the access validated.
You can also try a service account if you're doing small file transactions and don't need a user validation for the process of your script. Good Luck.
The problem was that I had to specify that I want offline access in the authentication process, the client side... The Google API's are horribly documented!!!

How to use Google Plus access token on backend side

I'm working on a mobile app based even on google plus api .
We have a client part formed by device such android or IOS that consuming JSon from a php server side back end.
Actually we obtain an access token from the client side, but when we try to pass it on the beck end side we can't handle the request and we got just mine data (even with other login in different pc) or bad errors...
wich is the right flow?
why I can't simply invoke setAccessToken() on $client obj with the passed token?
I try to put out some details:
we have an android client that i don't know how make the login but he can send me a valid Token by invoking mine php backend function.
here is the code of my php backend:
require_once 'src/Google_Client.php';
require_once 'src/contrib/Google_PlusService.php';
function getGooglePlusStream($tokenId)
{
$client = new Google_Client();
$client->setApplicationName("xxxxxxxxxxxxxxxxxxxx");
$client->setClientId('xxxxxxxxxxxxxxxx');
$client->setClientSecret('xxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
$client->setRedirectUri('xxxxxxxxxxxxxxxxxxxxxxx');
$client->setDeveloperKey('xxxxxxxxxxxxxxxxxxxxxxxxxxx');
$client->setScopes(array('https://www.googleapis.com/auth/plus.me',' https://www.googleapis.com/auth/plus.stream.read','https://www.googleapis.com/auth/plus.medi a.upload'));
$plus = new Google_PlusService($client);
$tokenazzo='{"access_token":"","token_type":"Bearer",
"expires_in":3600,"id_token":$tokenId,"
refresh_token":"XXXXXXXXXXXXXXXxx","created":1390214181}';
$client->setAccessToken($tokenazzo);
$client->authenticate();
$activities = $plus->activities->listActivities('me', 'public');
......... `

Connecting to the Google Sites API as a "Service Account"

I am trying to read a feed from a Google Sites account (Google apps).
I don't need my app to require every user to login so i created my ClientID as a "Service Account" in the "Google API console".
I have added this Client ID and the scope (https://sites.google.com/feeds/) to the "Mange API client access" page in my google apps control panel.
I connect using the code below, all constants are defined in my code with the right values.
// api dependencies
require_once(GOOGLE_API_PATH);
// create client object and set app name
$client = new Google_Client();
$client->setApplicationName(GOOGLE_API_NAME);
// set assertion credentials
$client->setAssertionCredentials(
new Google_AssertionCredentials(
GOOGLE_API_EMAIL,
array(GOOGLE_API_SCOPE),
file_get_contents(GOOGLE_API_PK)
));
$client->setClientId(GOOGLE_API_CLIENTID);
// create service
$req = new Google_HttpRequest("https://sites.google.com/feeds/content/<herismydomainname.com>/intranet");
$val = $client->getIo()->authenticatedRequest($req);
// The contacts api only returns XML responses.
$response = json_encode($val->getResponseBody());
print "<pre>" . print_r(json_decode($response, true), true) . "</pre>";
The response i get is "Not authorized to access this feed "
When i try to get this feed in the OAuth2.0 playground logging in using my google apps account i get the expected response.
What am i overlooking here?
Service accounts and Google Sites can't be used together currently. Google Apps provides a consumer secret that can be used to access data across your domain as Two-Legged OAuth within OAuth 1.0a.
Check out http://support.google.com/a/bin/answer.py?hl=en&answer=162105 for how to configure your Apps account, and the sample code at https://developers.google.com/gdata/docs/auth/oauth#2LeggedOAuth.

Categories