I am developing an app that allows users to see my own Google Analytics Data using Google API v3.
Everything I researched seems to indicate that users need to login into their Google accounts and grant my app the access before I can start querying the API; however, that's not what I want, I just need my users to see my own Analytics data. How can authorize the API to access my data.
I have the client ID and Client Secret, but the OAuth that's implemented by Google's API v3 is asking for an authorization token, which can only be obtained by getting the user to login into their google account (is that right?)
Is there a way to just login into my own Google Analytics account and display that information to the users?
I believe what you want to do is set up a Service Account:
https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmtAuthorization
"Useful for automated/offline/scheduled access to Google Analytics data for your own account. For example, to build a live dashboard of your own Google Analytics data and share it with other users.
There are a few steps you need to follow to configure service accounts to work with Google Analytics:
Register a project in the APIs Console.
In the Google APIs Console, under the API Access pane, create a
client ID with the Application Type set to Service Account.
Sign-in to Google Analytics and navigate to the Admin section.
Select the account for which you want the application to have access
to.
Add the email address, from the Client ID created in the APIs
Console from step #2, as a user of the selected Google Analytics
account.
Follow the instructions for Service Accounts to access Google Analytics data: https://developers.google.com/accounts/docs/OAuth2ServiceAccount"
You can use a refresh token for offline access. Once you get the refresh token, you can save it to a file or database and use that to access the data without an authorization redirect.
See Using a Refresh Token in the docs.
Also see: How can we access specific Google Analytics account data using API?
Here is a full Google Analytics reporting example implementation with service account including setup notes. Just wrote it after reading your question, I had the same problem.
<?php
// Service account code from http://stackoverflow.com/questions/18258593/using-a-service-account-getaccesstoken-is-returning-null
// Analytics code from https://code.google.com/p/google-api-php-client/source/browse/trunk/examples/analytics/simple.php?r=474
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_AnalyticsService.php';
// Set your client id, service account name (AKA "EMAIL ADDRESS"), and the path to your private key.
// For more information about obtaining these keys, visit:
// https://developers.google.com/console/help/#service_accounts
const CLIENT_ID = 'CLIENT ID';
const SERVICE_ACCOUNT_NAME = 'SERVICE ACCOUNT NAME (IS "EMAIL ADDRESS")';
const KEY_FILE = 'KEY FILE';
const SCOPE = 'https://www.googleapis.com/auth/analytics.readonly';
// OPEN GOOGLE ANALYTICS AND GRANT ACCESS TO YOUR PROFILE, THEN PASTE IN YOUR SERVICE_ACCOUNT_NAME
$key = file_get_contents(KEY_FILE);
$auth = new Google_Auth_AssertionCredentials(
SERVICE_ACCOUNT_NAME,
array(SCOPE),
$key
);
$client = new Google_Client();
$client->setScopes(array(SCOPE));
$client->setAssertionCredentials($auth);
$client->getAuth()->refreshTokenWithAssertion();
$accessToken = $client->getAccessToken();
$client->setClientId(CLIENT_ID);
$service = new Google_Service_Analytics($client);
?>
<!DOCTYPE html>
<html>
<head>
<title>Google Experiments Dashboard</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" media="screen">
</head>
<body class="container">
<h1>Your experiments</h1>
<table class="table"><tr><th><th>Experiment<th>Page<th>Started<th>Status
<?php
$progressClasses = array('progress-bar progress-bar-success','progress-bar progress-bar-info','progress-bar progress-bar-warning', 'progress-bar progress-bar-danger');
$profiles = $service->management_profiles->listManagementProfiles("~all", "~all");
foreach ($profiles['items'] as $profile) {
$experiments = $service->management_experiments->listManagementExperiments($profile['accountId'], $profile['webPropertyId'], $profile['id']);
foreach ($experiments['items'] as $experiment) {
echo "<tr>";
if ($experiment['status'] == 'RUNNING')
echo '<td><a class="btn btn-xs btn-success"><i class="glyphicon glyphicon-ok"></i></a>';
else
echo '<td><a class="btn btn-xs btn-danger"><i class="glyphicon glyphicon-remove"></i></a>';
$expHref = "https://www.google.com/analytics/web/?pli=1#siteopt-experiment/siteopt-detail/a{$profile['accountId']}w{$experiment['internalWebPropertyId']}p{$experiment['profileId']}/%3F_r.drilldown%3Danalytics.gwoExperimentId%3A{$experiment['id']}/";
echo "<td><a href='$expHref' target='_blank'>{$experiment['name']}</a>";
echo "<td>{$experiment['variations'][0]['url']}";
echo "<td>".date('Y-m-d',strtotime($experiment['startTime']));
echo "<td>";
echo '<div class="progress" style="width:400px">';
foreach ($experiment['variations'] as $i => $variation) {
echo '<div class="'.$progressClasses[$i].'" role="progressbar" style="width: '.(100*$variation['weight']).'%">'.$variation['name'].'</div>';
}
echo '</div>';
}
}
?>
Code with more documentation at https://gist.github.com/fulldecent/6728257
Related
I am implementing an Audio library manager which uses user's google drive as backend storage. I am using PHP (google-api-php-client-2.2.1) to get the user's authorization for accessing his/her google drive.
So far I am able to receive access token and refresh token using example code from google (https://developers.google.com/api-client-library/php/auth/web-app), and also tested by listing files of user's google drive.
However, I am not able to figure out programmatically which user has given authorization to my application. Just user's email address will do. I don't need any other information.
I am using the following code.
<?php
require_once 'google-api-php-client/vendor/autoload.php';
session_start();
$client = new Google_Client();
$client->setAuthConfig('client_secret.json'); //downloaded from google oauth credentials portal. It includes redirect URL
$client->setAccessType("offline"); // offline access
$client->setIncludeGrantedScopes(true); // incremental auth
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
if (! isset($_GET['code'])) {
//Get authorization and User consent from Google
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else { //Authorization completed
//Get access token
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$_SESSION['refresh_token'] = $client->getRefreshToken();
echo "Access Token<br>";
var_dump ($_SESSION['access_token']); //works
echo "<br>";
echo "Refresh Token<br>";
var_dump ($_SESSION['refresh_token']); //works
echo "<br>";
$service=new Google_Service_Oauth2($client);
echo "Auth2 Service created<br>"; //Getting this print
$usr_info=$service->userinfo;
echo "User Info<br>"; //Getting this print
var_dump ($usr_info); //Getting this print, Very long JSON structure. But info is mostly pertaining to my app...no user information showing here
echo "<br>";
//$usr_info_get = $usr_info->get(); //Throwing Error
//$usr_info_get = $usr_info->get(['email']); //Throwing Error
//$usr_info_get = $usr_info->get()['email']; //Throwing Error
echo "User Info Get<br>";
//var_dump ($usr_info_get);
echo "<br>";
}
?>
The class for userInfo is like this
class Google_Service_Oauth2_Resource_Userinfo extends Google_Service_Resource
{
/**
* (userinfo.get)
*
* #param array $optParams Optional parameters.
* #return Google_Service_Oauth2_Userinfoplus
*/
public function get($optParams = array())
{
$params = array();
$params = array_merge($params, $optParams);
return $this->call('get', array($params), "Google_Service_Oauth2_Userinfoplus");
}
}
The params for get() method should be optional, but
$userInfo->get()
also given me Server Error.
I am not finding anything else from my google search on this.
I tried this (6 year old thread) but code errors out (apiHttpRequest class not found)
How to identify a Google OAuth2 user?
I tried reading about openID but seems kinda complex. Also, not sure if google-api-php-client has helper class for openID.
I would really appreciate your help. Already spent 2+ days reading google api client php code but now up against the wall.
I have a website build with Laravel 4.2 and a controller that are accessible only to logged user:
Route::group(['prefix' => 'pannello-utente', 'before' => 'auth'], function ()
{
Route::get('elenco-animali/{nome?}', ['uses' => 'PazientiController#index']);
Route::get('download/{cartella}/{file}', ['uses' => 'PazientiController#download']);
});
the auth method request user to insert email and password.
In the PazientiController I have the __construct method that perform some queries that retrieve a code and use it in the other method:
public function __construct()
{
$this->current_user = Auth::user();
//Recupero il codice cliente salvato nel profilo utente
$this->codice = User::find($this->current_user->id)->first()->profile->codice_cliente;
}
This code is saved only in the database and, at the moment, no other application have it so I need to execute that query every time.
I need that, now via curl then via smartphone app, the user can access to the method, so I need users to log in before:
curl --user chri788#gmail.com:adminadmin localhost:8888/*****/public/pannello-utente/elenco-animali
But I get this:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="refresh" content="1;url=http://localhost:8888/*****/public/login" />
<title>Redirecting to http://localhost:8888/*****/public/login</title>
</head>
<body>
Redirecting to http://localhost:8888/****/public/login.
</body>
</html>
How can I access to that controller?
The --user flag for curl triggers HTTP Basic Authentication. Laravel supports this, but not with the auth filter - it needs the auth.basic filter.
You can write a custom filter that checks both auth and auth.basic, or you can provide a separate set of routes (maybe prefixed with api) that uses the alternate filter.
http://laravel.com/docs/4.2/security#http-basic-authentication
I would like to get content (posts) from a google+ page and post it to my website, as a feed. Is there any info how?
I read that current API does not allow that, but those topics were from the last year.
Thanks.
You can perform activities.list, without having to authenticate, by passing your "simple" key from the API console for a project created that has the Google+ service turned on. Access to the API calls is restricted to the authorized origins you set up in your project.
After you create the project, in the section "Simple API Access" there is an API key. Build your client with this key, your client id, and client secret:
<?
$client = new Google_Client();
$client->setDeveloperKey("YOUR_API_KEY");
$plus = new Google_PlusService($client);
$activities = $plus->activities->listActivities("+GooglePlusDevelopers", "public");
?>
<html><body><pre><? echo print_r($activities);?></pre></body></html>
A final note, make sure you use the latest Google+ PHP client.
After some time I found it.
http://code.google.com/p/google-plus-php-starter/
and this
https://developers.google.com/+/api/latest/activities/list
The only problem is that you need to log into your google app to do this. Any sugggestions would be apprecited.
Updating the correct answer, the class name has changed to Google_Service_Plus
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ .'/vendor/google/apiclient/src');
require_once __DIR__.'/vendor/autoload.php';
$client = new Google_Client();
$client->setDeveloperKey("YOUR_API_KEY");
$plus = new Google_Service_Plus($client);
$activities = $plus->activities->listActivities("+GooglePlusDevelopers", "public");
?>
$items = $activities->getItems();
foreach($items as $item) {
$object = $item->getObject();
?>
<div class="gpost">
<p><?php echo $object->getContent(); ?></p>
Read more
</div>
<?php } ?>
I am creating a basic Facebook app, and when a user without permission visits the app, they are redirected to the authorisation page. However, the page doesn't display, and I see the following error.
This content cannot be displayed in a frame
Opening it in a new window then shows the authorisation page for my app. Clicking 'Go to App' then takes me to the App, but in it's own window, away from Facebook. Going back to FB and reloding the App page now works.
Stranger yet, when I am logged out and go to my app page, I get a Facebook 404 page (4oh4.php).
I'm guessing that I am doing this wrong somehow, so can anyone see anything obvious wrong with my script? Thanks.
To see what is happening - http://apps.facebook.com/dyne_drewett_news/
<?php
require 'fb/facebook.php';
$fbconfig['appUrl'] = 'my-app-url'; // Create An instance of our Facebook Application.
$facebook = new Facebook(array(
'appId' => 'my-app-ID', // Entered correctly in actual script
'secret' => 'me-app-secret', // Entered correctly in actual script
'cookies' => 'true',
));
// Get the app User ID
$user = $facebook->getUser();
if($user) :
try{ // If the user has been authenticated then proceed
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e){
error_log($e);
$user = null;
}
endif;
// If the user is authenticated then generate the variable for the logout URL
if($user) :
$logoutUrl = $facebook->getLogoutUrl();
?>
<!-- My HTML goes here -->
<?php
else :
$loginUrl = $facebook->getLoginUrl();
header('Location: '.$loginUrl);
endif;
?>
Because you are working in an iframe, you'll have to execute JavaScript redirects. Only that way will you be able to redirect the top most frame -
echo "<script language=javascript>";
echo "top.location.href ='".$url."';";
echo "</script>";
exit();
This is the only way to do complete redirects within a Facebook application. Any other redirect (with PHP for example) will only redirect the user within the iframe...
i'm using the examples provided in the "google-api-php-client"-Library (http://code.google.com/p/google-api-php-client/) to implement user login and authorization on my website with google services.
I didn't make any changes to the examples, except adding my Client-ID, etc..
The authorization itself works fine: Users can login and i can fetch the provided informations.
However, when leaving the page, the whole authorization procedure is called again; users are not remembered and need to grant permissions again, which is some kind of annoying and not typical for google-logins as i know them.
For example: On stackoverflow, i'm logged in with my google account.
Whenever i revisit this site, i'm logged in automaticly, or (if logged out) just have to log in again - i do not have to confirm the general rights again.
Using the examples on my site however, forces the user to allow access whenever the site is visited again.
Did i make any mistakes, when using the examples?
What do i have to do, to avoid the permission request over and over again?
Thanks in advance for any kind of help!
Use this code for first time to retrieve access_code and save it to database:
<?php
require 'google-api-php-client/src/Google_Client.php';
require 'google-api-php-client/src/contrib/Google_DriveService.php';
require 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
session_start();
$client = new Google_Client();
$client->setClientId(CLIENT_ID);
$client->setClientSecret(CLIENT_SECRET);
$client->setRedirectUri(REDIRECT_URI);
$client->setScopes(array(
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile'));
$client->setUseObjects(true);
$service = new Google_DriveService($client);
$client->authenticate();
$_SESSION['token'] = $client->getAccessToken();
const ACCESS_TOKEN=$_SESSION['token'];
//code here to save in database
?>
Once ACCESS_TOKEN is saved in database change code to:
<?php
require 'google-api-php-client/src/Google_Client.php';
require 'google-api-php-client/src/contrib/Google_DriveService.php';
require 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
session_start();
$client = new Google_Client();
$client->setClientId(CLIENT_ID);
$client->setClientSecret(CLIENT_SECRET);
$client->setRedirectUri(REDIRECT_URI);
$client->setScopes(array(
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile'));
$client->setUseObjects(true);
$service = new Google_DriveService($client);
//ACCESS_TOKEN is already saved in database, is being saved on first time login.
$_SESSION['access_token'] = ACCESS_TOKEN;
if (isset($_SESSION['access_token'])) {
$client->setAccessToken($_SESSION['access_token']);
}
if ($client->getAccessToken())
{
$userinfo = $service->about->get();
echo '<script>console.log('.json_encode($userinfo).');</script>';
$userinfoService = new Google_OAuth2Service($client);
$user = $userinfoService->userinfo->get();
echo '<script>console.log('.json_encode($user).');</script>';
}
?>
That works fine for me.
Based on the kaushal's answer:
<?php
require_once 'globals.php';
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_DriveService.php';
$client = new Google_Client();
// Get your credentials from the APIs Console
$client->setClientId('YOUR_ID');
$client->setClientSecret('YOUR_SECRET');
$client->setRedirectUri('REDIRECT_URI');
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
$service = new Google_DriveService($client);
$client->setUseObjects(true);
//if no token in the session
if ($_SESSION['google_token'] == '') {
//get stored token from DB
$sToken = $oDb->getOne("SELECT `google_token` FROM `users` WHERE `u_id` = " . (int)$_SESSION['user_id']);
//if no stored token in DB
if ($sToken == '') {
//autentificate user
$client->authenticate();
//get new token
$token = $client->getAccessToken();
//set token in session
$_SESSION['google_token'] = $token;
// set token in DB
$oDb->Query("UPDATE `users` SET `google_token`='$token' WHERE `u_id` = " . (int)$_SESSION['user_id']);
} else {
$_SESSION['google_token'] = $sToken;
}
}
$client->setAccessToken($_SESSION['google_token']);
//do what you wanna do with clients drive here
?>
The Google Drive SDK documentation includes a complete PHP sample application that you can use as a reference to get started:
https://developers.google.com/drive/examples/php
Basically, once the user is logged in and you retrieve access token and refresh token, you store those credentials in a database and reuse them instead of asking the user to authenticate every time.