alooi14 / analytics-issues

Automatically exported from code.google.com/p/analytics-issues
0 stars 1 forks source link

Embed API does not work with Server Side generated OAuth token for ServiceAccount connected to GA View. #496

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
---------------------------------------------------------------------------
This is for the Embed API
https://developers.google.com/analytics/devguides/reporting/embed/v1/
---------------------------------------------------------------------------
Issue summary:
Provide a brief summary of the issue you're experiencing.

Steps to reproduce issue:
1. I described the problem deeply here 
http://stackoverflow.com/questions/25896826/using-google-analytics-to-show-subse
t-of-data-for-customers-of-web-application-u

2. I created Service Account, added it to View in GA, generated OAuth token on 
server side and wanted to provide the token on frontend in Javascript so that 
the charts are displayed. I modified the 1-basic-dashboard.html example from 
embed-api-demos that are available on github to use 

  gapi.analytics.auth.authorize({
    container: 'auth',
    clientid: 'Service email address', // I also tried webapp email address
    serverAuth: {
      access_token: 'Server side generated token with p12 keys'
    }
  });

3. Visit the website 1-basic-dashboard.html locally hosted.

Expected output:
I expected to see a dashboard 
https://ga-dev-tools.appspot.com/demos/embed-api/1-basic-dashboard.html with 
the ability to browse the one View that I authorized my Service to.

Actual results:
There is no dashboard and no error in the console. In the Networking section of 
Chrome I can see that request are going to GA and they are answered with 200 OK 
response but nothing is being displayed. In my previous attempts when I was 
doing something obviously wrong the Netowrking responses were showing 
"Unauthorized". It is not like that. 200 OK, data seems to be there in the 
responses but nothing popsup in HTML.

Notes:
Provide any additional information which might be useful here. Feel free to
attach screenshots or sample code which demonstrates the issue being
described.

Original issue reported on code.google.com by robert.p...@gmail.com on 18 Sep 2014 at 7:59

GoogleCodeExporter commented 9 years ago
Is the server side officialy supported ?

Original comment by ypasqu...@idm2008.com on 23 Sep 2014 at 8:05

GoogleCodeExporter commented 9 years ago
I don't know. I created this ticket believing that it is. The parameter name 
"serverAuth" would indicate it is. 

Original comment by robert.p...@gmail.com on 28 Sep 2014 at 8:55

GoogleCodeExporter commented 9 years ago
Robert, I've just tried this myself and it's definitely possible, so I assume 
you have a mistake somewhere in your code. To verify, can you try this demo I 
put together?

All you have to do is replace the `ids` and `access_token` constants with your 
own data. Let me know if it works.

http://jsbin.com/vukezoheyeco/3/edit

Original comment by philipwa...@google.com on 29 Sep 2014 at 6:57

GoogleCodeExporter commented 9 years ago
@Philip, I tried your demo code with my credentials and it doesn't work - I get 
401 Unauthorised Invalid Credentials.

I 'm pretty puzzled about this, because the Client Side verification 
credentials for the same account and IDS work just fine. I tried to create a 
totally new service account as well, but it did not make any difference. 

I'm starting to think I'm missing something really small and trivial so just to 
be sure; what really is the format of the access token you refer to? I have 
used only the CLIENT ID, but does it contain something else as well?

Original comment by jennarii...@gmail.com on 13 Oct 2014 at 12:28

GoogleCodeExporter commented 9 years ago
This has had me tripped up for a couple of days And I just solved the problem 
for me.

The token that gets generated make sure it includes the scope of 
"https://www.googleapis.com/auth/analytics.readonly". I included only 
"https://www.googleapis.com/auth/analytics" and that is not enough. I dont know 
why, it seems very wrong but thats fixed the problem. 

I am now generating my token like this...

$cred = new Google_Auth_AssertionCredentials(
    $service_account_name,
    array("https://www.googleapis.com/auth/analytics","https://www.googleapis.com/auth/analytics.readonly","https://www.googleapis.com/auth/analytics.manage.users"),
    $key
);

Goodluck I hope this helps.

Original comment by ssweb...@gmail.com on 28 Oct 2014 at 7:07

GoogleCodeExporter commented 9 years ago
I am having the same problem but having both analytics and analytics.readonly 
did not solve it. This is my js code:

gapi.analytics.auth.authorize({
   serverAuth: {
    access_token: '<?php echo $access_token; ?>'
   }
}); 

I've tried several different ways of adding scopes on the server side but that 
doesn't seem to affect it either.

Original comment by ch...@golevel.com on 31 Oct 2014 at 5:15

GoogleCodeExporter commented 9 years ago
Does anyone have example working code that we can use to troubleshoot using the 
serverAuth accessToken? Google's API docs say that this is possible but they 
don't have any working demo code that actually demonstrates it.

And for those that do have this working with the GA Embed API, what scope(s) 
did you include with your initial authentication?

Original comment by r...@golevel.com on 31 Oct 2014 at 5:18

GoogleCodeExporter commented 9 years ago
Unfortunately for me also not working. It does not show anything. Please please 
please someone can tell me where I am wrong? 

Here is my code:

<?PHP

$client_id = CLIENT_ID;
$client_secret = CLIENT_SECRET;
$redirect_uri = URL;

$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->addScope("https://www.googleapis.com/auth/analytics.readonly");
$client->setAccessType('offline');

$service = new Google_Service_Urlshortener($client);

if (isset($_GET['code'])) {

    $client->authenticate($_GET['code']);
    $googleToken = $client->getAccessToken();       
    $objGoogleToken= json_decode($googleToken);
    $_SESSION['access_token'] = $objGoogleToken->access_token;
    $_SESSION['refress_access_token'] = $objGoogleToken->refresh_token;

}

?>

<script>
(function(w,d,s,g,js,fjs){
  g=w.gapi||(w.gapi={});g.analytics={q:[],ready:function(cb){this.q.push(cb)}};
  js=d.createElement(s);fjs=d.getElementsByTagName(s)[0];
  js.src='https://apis.google.com/js/platform.js';
  fjs.parentNode.insertBefore(js,fjs);js.onload=function(){g.load('analytics')};
}(window,document,'script'));
</script>

<script>
gapi.analytics.ready(function() {

  // Step 3: Authorize the user.

  var CLIENT_ID = 'Insert your client ID here';

  gapi.analytics.auth.authorize({
   serverAuth: {
                access_token: '<?php echo $_SESSION['access_token'];?>'
    }
  });

  // Step 4: Create the view selector.

  var viewSelector = new gapi.analytics.ViewSelector({
    container: 'view-selector'
  });

  // Step 5: Create the timeline chart.

  var timeline = new gapi.analytics.googleCharts.DataChart({
    reportType: 'ga',
    query: {
      'dimensions': 'ga:date',
      'metrics': 'ga:sessions',
      'start-date': '30daysAgo',
      'end-date': 'yesterday',
    },
    chart: {
      type: 'LINE',
      container: 'timeline'
    }
  });

  // Step 6: Hook up the components to work together.

  gapi.analytics.auth.on('success', function(response) {
    viewSelector.execute();
  });

  viewSelector.on('change', function(ids) {
    var newIds = {
      query: {
        ids: ids
      }
    }
    timeline.set(newIds).execute();
  });
});

Original comment by viral2...@gmail.com on 31 Oct 2014 at 5:49

GoogleCodeExporter commented 9 years ago
Are you getting an access token that you can run queries with outside of the 
Embed API? All the Embed API does is append your access token to the query made 
by the core reporting API as specified here:
https://developers.google.com/analytics/devguides/reporting/core/v3/reference#q_
summary

Please try your access token with a regular query. If it doesn't work then 
there's some other problem.

Original comment by philipwa...@google.com on 31 Oct 2014 at 9:03

GoogleCodeExporter commented 9 years ago
Changing

gapi.analytics.auth.authorize({
    serverAuth: {
        access_token: '<?php echo $_SESSION['access_token'];?>'
    }
});

to

gapi.analytics.auth.authorize({
    serverAuth: <?php echo $_SESSION['service_token']; ?>
});

fixed the authentication issue for me.

Original comment by webt...@clark.wa.gov on 11 Mar 2015 at 7:22

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I somewhat encountered the same problem. I had a valid access token but got an 
empty page without any errors. The problem is in the fact that the 
authentication succes callback is never called when you're authorizing with an 
access token. 

Manually calling viewSelector.execute() solved the problem for me :)

Original comment by 93jo...@gmail.com on 2 May 2015 at 3:05

GoogleCodeExporter commented 9 years ago
Parcero se hace asi:

<!DOCTYPE html>
<html>
<head>
  <title>Embed API Demo</title>
</head>
<body>

<div id="embed-api-auth-container"></div>
<div id="timeline"></div>
<div id="view-selector"></div>
<script>
(function(w,d,s,g,js,fjs){
  g=w.gapi||(w.gapi={});g.analytics={q:[],ready:function(cb){this.q.push(cb)}};
  js=d.createElement(s);fjs=d.getElementsByTagName(s)[0];
  js.src='https://apis.google.com/js/platform.js';
  fjs.parentNode.insertBefore(js,fjs);js.onload=function(){g.load('analytics')};
}(window,document,'script'));
</script>

<script>
gapi.analytics.ready(function() {

  // Step 3: Authorize the user.

  gapi.analytics.auth.authorize({
    container: 'embed-api-auth-container',
    clientid: '519191512891-lb6pnsr9utk54ta3sm11plpfce285q6t.apps.googleusercontent.com',
  });

  // Step 4: Create the view selector.

  var viewSelector = new gapi.analytics.ViewSelector({
    container: 'view-selector'
  });

    // Render the view selector to the page.
  viewSelector.execute();

  // Step 5: Create the timeline chart.

  var timeline = new gapi.analytics.googleCharts.DataChart({
    reportType: 'ga',
    query: {
      'dimensions': 'ga:date',
      'metrics': 'ga:sessions',
      'start-date': '30daysAgo',
      'end-date': 'yesterday',
    },
    chart: {
      type: 'LINE',
      container: 'timeline'
    }
  });

  // Step 6: Hook up the components to work together.

  gapi.analytics.auth.on('success', function(response) {
    viewSelector.execute();
  });

  viewSelector.on('change', function(ids) {
    var newIds = {
      query: {
        ids: ids
      }
    }
    timeline.set(newIds).execute();
  });
});
</script>
</body>
</html>

Original comment by g3agen...@gmail.com on 29 May 2015 at 12:29

GoogleCodeExporter commented 9 years ago
I had this issue as well - it turns out that when you use the serverAuth 
property when calling authorize, the call is no longer asynchronous and doesn't 
trigger the success callback (not mentioned in docs).

You need to call viewSelector.execute() manually in this scanrio:

<!DOCTYPE html>
<html>
<head>
  <title>Embed API Demo</title>
</head>
<body>

<!-- Step 1: Create the containing elements. -->

<section id="auth-button"></section>
<section id="view-selector"></section>
<section id="timeline"></section>

<!-- Step 2: Load the library. -->

<script>
(function(w,d,s,g,js,fjs){
  g=w.gapi||(w.gapi={});g.analytics={q:[],ready:function(cb){this.q.push(cb)}};
  js=d.createElement(s);fjs=d.getElementsByTagName(s)[0];
  js.src='https://apis.google.com/js/platform.js';
  fjs.parentNode.insertBefore(js,fjs);js.onload=function(){g.load('analytics')};
}(window,document,'script'));
</script>

<script>
gapi.analytics.ready(function() {

  // Step 3: Authorize the user.

  var SERVER_ACCESS_TOKEN = ;

  gapi.analytics.auth.authorize({
    serverAuth: [YOUR SERVER ACCESS TOKEN OBJECT HERE] 
  });

  // Step 4: Create the view selector.

  var viewSelector = new gapi.analytics.ViewSelector({
    container: 'view-selector'
  });

  // Step 5: Create the timeline chart.

  var timeline = new gapi.analytics.googleCharts.DataChart({
    reportType: 'ga',
    query: {
      'dimensions': 'ga:date',
      'metrics': 'ga:sessions',
      'start-date': '30daysAgo',
      'end-date': 'yesterday',
    },
    chart: {
      type: 'LINE',
      container: 'timeline'
    }
  });

  // YOU MUST CALL THIS MANUALLY HERE INSTEAD OF WAITING FOR CALLBACK
  viewSelector.execute();

  // Step 6: Hook up the components to work together.

  // gapi.analytics.auth.on('success', function(response) {
  //   alert("!");
  //   viewSelector.execute();
  // });

  viewSelector.on('change', function(ids) {
    var newIds = {
      query: {
        ids: ids
      }
    }
    timeline.set(newIds).execute();
  });
});
</script>
</body>
</html>

See also:
http://stackoverflow.com/questions/25896826/using-google-analytics-to-show-subse
t-of-data-for-customers-of-web-application-u

Original comment by steve.br...@gmail.com on 29 May 2015 at 2:57