Google Analytics API Automated Login - google-analytics

I have this panel that i'm developing at my company where i will show the user's information from Google Analytics but i don't want the user to authorize or log in with his account every time he comes to the panel.
What i would like to do is: on the first time using my panel he would connect his Google account and i would save some info and on the next time he connects at my panel i would use this saved info to log on his account so i can list the Analytics info without ask for his permission or list that info even if he's not connected on is Google account right now.
Basically i would log in his account automatically and permit the 'app' to show the information.
I already have some code that connects on the API if he is connected on is Google account, but when he's not i get the login screen where he has to provide his email e password.
What i have so far is this:
<?php
require_once 'Google/Client.php';
require_once 'Google/Service/Analytics.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Google Analytics PHP Starter Application");
$client->setClientId('KEY');
$client->setClientSecret('SECRET');
$client->setRedirectUri('RETURN URI');
$client->setScopes('https://www.googleapis.com/auth/analytics.readonly');
$client->setAccessType('offline');
$service = new Google_Service_Analytics($client);
if(isset($_GET['logout']))
{
unset($_SESSION['token']);
}
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($client->getAccessToken())
{
$props = $service->management_webproperties->listManagementWebproperties("12008145");//~all
print "<h1>Web Properties</h1><pre>" . print_r($props, true) . "</pre>";
$accounts = $service->management_accounts->listManagementAccounts();
//print "<h1>Accounts</h1><pre>" . print_r($accounts, true) . "</pre>";
$segments = $service->management_segments->listManagementSegments();
//print "<h1>Segments</h1><pre>" . print_r($segments, true) . "</pre>";
$goals = $service->management_goals->listManagementGoals("~all", "~all", "~all");
//print "<h1>Goals</h1><pre>" . print_r($goals, true) . "</pre>";
$_SESSION['token'] = $client->getAccessToken();
}
else
{
$authUrl = $client->createAuthUrl();
header("Location: " . $authUrl);
}
?>
Is there any way to do that ? I have looked for it around everywhere and couldn't find something near it.

In google Api's, when user authenticate the first time, you receive a CODE (which you are already getting i suppose). Use this code to get refresh token (lifetime is (always), until and unless, user revokes the permissions). Save this refresh token in Database for further use. Refresh token is used to get access token(lifetime is a short time, returned in the expires in argument). Access token is to give you access to your user's data for some time. You can keep using refresh token to get access token whenever you need to access your user's data.
Whenever you want to access user's data, use refresh token to get access token and then use that access token to get user's data.
In your case, you are using google api php client, you can use Methods in Client.php like:
getAccessToken()---to get refresh token the first time. When you call this method, you get back a json in a form: let this json name be $accessToken
$accessToken = {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
"expires_in":3600,"id_token":"TOKEN", "created":1320790426}
parse json to take refresh_token($refreshToken = $accessToken.refresh_token) and save it for later use.
setAccessToken($accessToken)---call this to set the OAuth access token.
refreshToken($refreshToken)---Fetches a fresh OAuth access token with the given refresh token.
For further clearity, look at Client.php and also read:
https://developers.google.com/accounts/docs/OAuth2WebServer

Related

Firebase login with Facebook provider returns empty token after password reset

I have a project consisting of an Android and an iOS client connected to a PHP backend. Login is set up via Firebase with email, Facebook and Google providers and works OK. Password resetting also works; I obtain the link on the backend given the email and send the password reset link to the client if the email exists. The link is obtained like this:
$auth = app('firebase.auth');
$link = $auth->getPasswordResetLink($request->email); // The user provided email is passed in if it exists in the database
// Then the link is sent back to the user in an email.
Now the problem is not critical since it's not an everyday scenario, but it comes when logging in with Facebook (it doesn't happen with Google), log out, then the user clicks on "Did you forget your password?" and obtains the link, and resets the password. At this moment, in Firebase, the login provider changes back from Facebook to email as expected, but if the user tries to login again with Facebook, the signin itself doesn't throw any error (and I obtain expected user data like the Firebase ID, name, etc.) but the access and refresh tokens are empty.
This is the code I'm using to sign in the user:
$auth = app('firebase.auth');
$signInToken = $request->token; // The token obtained at the client's side, needed to perform the login in Firebase
$signInProvider = $request->provider; // This will be 'google.com' or 'facebook.com'
try {
$signInResult = $auth->signInWithIdpAccessToken($signInProvider, $signInToken, null, null, null, null);
// The following traces are all empty in the described case
Log::debug('Sign in result idToken: ' . $signInResult->idToken());
Log::debug('Sign in result accessToken: ' . $signInResult->accessToken());
Log::debug('Sign in result tokenResponse: ' . print_r($signInResult->asTokenResponse(), true));
//But this data() object indeed shows data from the user logged in:
Log::debug('Sign in result data: ' . print_r($signInResult->data(), true));
} catch(FailedToSignIn $e) {
Log::debug('Error signing in with provider: ' . $e->getMessage()); //This doesn't get called in the described scenario
}
Any idea what could be the problem?

Which PHP Script File is needed for ical() class in Google Calendar PHP API v3

I am getting an error in a PHP script I am building:
Fatal error: Class 'ical' not found in /home/abc/public_html/app/mods/googleCalendar_3.0/cache_events.php on line 74
Here is a snippet from my script file:
define('CLIENT_ID', 'ASDLJJLDSJLASDJLajdl;jdsljkASD;LKJASDLKJASD.apps.googleusercontent.com');
require_once('autoload.php'); // 2014-11-24 part of /usr/local/lib/php/google-api-php-client
require_once('/usr/local/lib/php/google-api-php-client/src/Google/Client.php'); // 2014-11-25
require_once('/usr/local/lib/php/google-api-php-client/src/Google/Service/Calendar.php'); // 2014-11-25
$ical = new ical('https://www.google.com/calendar/ical/CLIENT-ID/public/basic.ics');
$eventListArray = array_filter($ical -> events(), "locationfilter");
$eventCount = count($eventListArray);
print_r($eventListArray); echo "<br>";
echo "Event Count:" . $eventCount;echo "<br>";
exit;
I am simply trying to retrieve all events in my public calendar
Notes:
Calendar is publicly viewable
Just to make sure, I added my Auth & API's > Credentials > Service Account > Email Address to it just to be safe
If you want to use a service account your code is off quite a bit. I cant test this code my local webserver is acting up but it should be close you may have to tweek the $service->Events->list(); part it was kind of a guess. Make sure that you have the Service account email address added as a user on the calendar in question and it should work.
session_start();
require_once 'Google/Client.php';
require_once 'Google/Service/Calendar.php';
/************************************************
The following 3 values an befound in the setting
for the application you created on Google
Developers console. Developers console.
The Key file should be placed in a location
that is not accessable from the web. outside of
web root. web root.
In order to access your GA account you must
Add the Email address as a user at the
ACCOUNT Level in the GA admin.
************************************************/
$client_id = '1046123799103-nk421gjc2v8mlr2qnmmqaak04ntb1dbp.apps.googleusercontent.com';
$Email_address = '1046123799103-nk421gjc2v8mlr2qnmmqaak04ntb1dbp#developer.gserviceaccount.com';
$key_file_location = '629751513db09cd21a941399389f33e5abd633c9-privatekey.p12';
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$key = file_get_contents($key_file_location);
// seproate additional scopes with a comma
$scopes ="https://www.googleapis.com/auth/calendar";
$cred = new Google_Auth_AssertionCredentials(
$Email_address,
array($scopes),
$key
);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$service = new Google_Service_Calendar($client);
// you should only need to do this once print this and you will
// find the calendarId for the one you are looking for.
$calendars = $service->calendarList->list();
$events = $service->events->list($yourCalendarID);
Note: all you need is the Google Dir you can remove everything above that you dont really need it. Code was edited from the only tutorial i have that shows this in PHP.

Cannot Authenticate Salesforce in a Wordpress Plugin

I'm getting an error (INVALID_SESSION_ID) when trying to send an authenticated GET request to Salesforce.com.
Here is the plug-in in its entirety, which basically just outputs the body of the REST response to whatever page has the [MembershipTables] shortcode:
if (!class_exists('WP_Http')) {
include_once(ABSPATH . WPINC . '/class-http.php');
}
// This is obviously the real username
$username = 'xxxx#xxxx.xxx';
// And this is obviously the real password concatonated with the security token
$password = 'xxxxxxxxxxxxxx';
function getMembershipTables() {
$api_url = 'https://na15.salesforce.com/services/apexrest/directory';
$headers = array('Authorization' => 'Basic ' . base64_encode("$username:$password"));
$args = array('headers' => $headers);
$request = new WP_Http;
$result = $request->request($api_url, $args);
$body = $result['body'];
echo "$body";
}
add_shortcode( 'MembershipTables', 'getMembershipTables' );
I should note that I can successfully hit this endpoint with Curl, though I use a session token I get from Salesforce using the old SOAP API to keep it equivalent (i.e., no client id/secret).
Am I doing something wrong with WP_Http? Or cannot I not authenticate a salesforce.com request using basic auth?
Thanks.
The salesforce API does not support Basic authentication, you need to call it with a sessionId. You can obtain a sessionId by various methods include interactive & programatic OAuth2 flows, and via a Soap login call.
Basis Interactive had a similar problem to solve. When I worked on the project I opted to to call the SalesForce CRM via the preset form plugin and a custom JS Cookie PHP Wordpress Plugin. We had this problem easily resolved by developing custom calls to SalesForce CRM via a getRequest in PHP passing data to the SalesForce CRM.
Test Site in Use:
http://newtest.medullan.com/wp/?page_id=3089
Here is the code and recycle the logical queries
Download Link:
http://basisinteractive.net/webdesign.html#wordpress

application loaded in iframe on facebook

I have an app loaded in iframe on facebook.
But after allow and redirected to my facekooksite from facebook authorization i cant fetch the "code" from the querrystring from within my code (because loaded in an iframe on facebook)
How will i be able to fetch the "code" parameter?
I guess you are following the server-side authentication flow. But since you are using Apps on Facebook, this flow will change since Facebook is sending a signed_request to your canvas iframe:
<?php
$app_id = "YOUR_APP_ID";
$canvas_page = "YOUR_CANVAS_PAGE_URL";
$auth_url = "https://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($canvas_page);
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if (empty($data["user_id"])) {
echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
echo ("Welcome User: " . $data["user_id"]);
}
?>
Obviously when you are on Facebook, the user is either connected to your app or not so if he/she is not connected then you redirect them to the authentication URL.

PHP SDK: How do I capture the access token after user auths app?

This is for a canvas app on the Facebook Platform using the new(est) Facebook PHP SDK.
We are using the PHP example from the Facebook tutorial (https://developers.facebook.com/docs/appsonfacebook/tutorial/) to trigger the OAuth dialog and get the test user to the redirect URL.
At the redirect URL, we use the PHP example from the Facebook signed request docs page (https://developers.facebook.com/docs/authentication/signed_request/) and our test users can successfully authorize the app.
However, after the test user auths the app, we are not able to capture the access token and its expiration. We can see it in the address bar appended to the redirect URL, but it does not show up in the $_REQUEST array. If we add {$access_token = $facebook->getAccessToken();} to the redirect URL page, it shows a value for the access token, but the value it shows is not the full token string that we see when we click on Show Token in the Test User Roles page (which we believe is the correct access token for the test user).
Here is an example of the redirect URL with an access token appended:
http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php#access_token=126736467765%7C2.AQDavId8oL80P5t9.3600.1315522800.1-100002908746828%7CJICJwM1P_97tKmqkEO5pXDCf-7Y&expires_in=6008
Here is what var_dump shows for the $REQUEST array for that same page:
array(3) { ["_qca"]=> string(26) "P0-709927483-1291994912966" ["__switchTo5x"]=> string(2) "30" ["PHPSESSID"]=> string(26) "euois02ead39ijumca7nffblh2" }
We have no idea why the $_REQUEST array varies from the values appended to the URL, and more importantly -- how to capture the access token and its expiration date.
Can someone show us a working example of how they capture this data after running the parse_signed_request($signed_request, $secret) function on the redirect page? Thanks!
ADDITIONAL INFO:
Here is the pertinent code from A) our test index page, and B) our test redirect page. If we use our text index page as the redirect url it gets stuck in an endless loop -- because the user is never identified.
A) Index Page
// Create kk-fb app instance
$facebook = new Facebook(array(
'appId' => KKFB_ID,
'secret' => KKFB_KY,
'oauth' => true,
));
$app_id = KKFB_ID;
$secret = KKFB_KY;
$canvas_auth = 'http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php';
$auth_url = "https://www.facebook.com/dialog/oauth?"
. "client_id=" . $app_id
. "&redirect_uri=" . urlencode($canvas_auth)
. "&response_type=token"
. "&scope=email,publish_stream";
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if (empty($data["user_id"])) {
echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
echo ("Welcome User: " . $data["user_id"]);
}
B) Redirect Page
// Create kk-fb app instance
$facebook = new Facebook(array(
'appId' => KKFB_ID,
'secret' => KKFB_KY,
'oauth' => true,
));
$app_id = KKFB_ID;
$secret = KKFB_KY;
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
$user = $facebook->getUser();
$access_token = $facebook->getAccessToken();
echo "User: $user <br>";
echo "Access Token: $access_token <br>";
echo "Signed Request: $signed_request <br>";
var_dump($_REQUEST);
Here is what shows up as these echo results:
User: 0
Access Token: 126736467765|**SECRET**
Signed Request:
array(3) { ["_qca"]=> string(26) "P0-709927483-1291994912966" ["_switchTo5x"]=> string(2) "30" ["PHPSESSID"]=> string(26) "frugi545cdl15gjind1fnv6pq1" }
Interestingly, when the test user goes back to the index page the if condition is satisfied and we can get the correct access token:
Welcome User: 100002908746828
Access Token: 126736467765|2.AQBgcyzfu75IMCjw.3600.1315544400.1-100002908746828|m5IYEm976tJAkbTLdxHAhhgKmz8
Obviously, we are still missing something!? Also, we need to learn how to get the expiration time as a variable too so we can store both of these in our database.
OK, let's try this again.
Server-side vs Client-side Authentication
You are exclusively using the PHP SDK, so you want to do server-side authentication, where the authentication code is sent to the server over HTTP via the URL. This will allow you to fetch an access token for the user on the first page load after auth (in your case, the redirect page). The auth_url you are currently constructing is setting response_type=token, which forces the redirect to use client-side auth mode and set the token in the URL fragment instead of in the query. You should remove that parameter completely. In fact, I highly recommend you just use the PHP SDK instead of constructing that URL yourself. See example below.
Application Access Tokens
The odd-looking access token 126736467765|SECRET is your application access token, which is composed of your app ID and secret key. The application access token is returned by getAccessToken() if no user access token is available (because some API calls require at least some sort of access token). This also means that you've revealed your secret key to the world via this blog post, so you should reset your app secret otherwise anyone will be able to make API calls on your behalf. I highly recommend you elide parts of your access tokens if you share them with others.
Token Expiration
The OAuth 2.0 flow and v3.1.1 of the PHP SDK don't make determining the expiration time of a token all that easy. I would suggest attempting to make the API call, and then refreshing the token if the API call fails with an OAuthException. Tokens can be invalid even if they haven't expired, so this deals with more cases. However, if you still want to maintain the expiration date on your end, you might just want to extract it from the token itself. If you have an expiring token, then the expiration timestamp will be contained within that string. Here's a function I put together quickly to extract that:
function extractExpirationFromToken($access_token) {
$segments = explode('|', $access_token);
if(count($segments) < 2) { return 0; }
$segments = explode('.', $segments[1]);
if(count($segments) < 4) { return 0; }
$expires = $segments[3];
$dash_pos = strrpos($expires, '-');
if($dash_pos !== false) {
$expires = substr($expires, 0, $dash_pos);
}
return $expires;
}
New Index Page Code
// Create kk-fb app instance
$facebook = new Facebook(array(
'appId' => KKFB_ID,
'secret' => KKFB_KY,
));
$canvas_auth = 'http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php';
$auth_url = $facebook->getLoginUrl(array(
'scope' => 'email,publish_stream',
'redirect_uri' => $canvas_auth, // you could just redirect back to this index page though
));
$user = $facebook->getUser();
if (empty($user)) {
echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
echo ("Welcome User: " . $user);
}
Redirect Page
I don't think you need this page at all. You could just redirect the user back to your original index page.
// Create kk-fb app instance
$facebook = new Facebook(array(
'appId' => KKFB_ID,
'secret' => KKFB_KY,
));
$user = $facebook->getUser();
$access_token = $facebook->getAccessToken();
// also copy the function definition given earlier
$expiration = extractExpirationFromToken($access_token);
echo "User: $user <br>";
echo "Access Token: $access_token <br>";
echo "Expiration: $expiration <br>";
echo "Request: <br>";
var_dump($_REQUEST);
You can use the facebook build in method getAccessToken() for example;
$access_token = $facebook->getAccessToken();
This will give you the access token to your variable, now if you are getting it empty, remember to first check if the fuid is being properly catch, if it isn't you might need to review your settings be sure your "App Domain" is set this part is very important after setting it correctly you need to reset your app secret, then set your new values in your auth code. Hope this help, let me know :)
pd. Also remember to keep the scope of your variables visible in your whole php file or class.
Problem
The access_token in your pasted URL is not part of the query string, but instead contained in the URL fragment (after the #). URL fragments are not sent to the web server, and are readable only by client-side code like Javascript. Therefore the PHP SDK only sees http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php, which is why $_REQUEST does not contain an access_token key.
Questions / Notes
What are you using for your redirect_uri? I think you want to be using something like http://apps.facebook.com/your_canvas_url/
You shouldn't need to call parse_signed_request yourself or copy any code from the signed request page. The PHP SDK will do that for you. Just call:
$facebook = new Facebook(array(
'appId' => '…',
'secret' => '…',
));
$access_token = $facebook->getAccessToken();
Possible solutions
Also use the Facebook Javascript SDK. You can start by adding its <script> tag in your destination page (kk-fb-auth.php) (see the docs for full details; don't forget to set oauth: true). The JS SDK should set a cookie (named fbsr_126736467765) which the PHP SDK will be able to read via $_REQUEST or $_COOKIE on subsequent page loads.
If you want to do this with PHP, you can get the user's access token with a separate call to the Graph API at your redirect_uri. For this you need to change the response_type of your $auth_url in your index page to "code" or "code token".
Then, at your redirect page, Facebook will add a "code" parameter in the querystring. This API call will return you the full access_token and expiration time:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&
redirect_uri=YOUR_URL&
client_secret=YOUR_APP_SECRET&
code=$_REQUEST['code']
For more information you can refer to the docs on authentication.

Resources