Analytics API - 403 Forbidden

1,503 views
Skip to first unread message

SS

unread,
Jul 4, 2012, 10:54:59 AM7/4/12
to google-analytics...@googlegroups.com

Hi,

I am trying to access some metrics through the Google Analytics API through JQuery $getJSON.

 

My initial authorisation request is as follows, which requests permission for 2 scopes - I am using this to request an access_token which seems to work correctly.


<a href='https://accounts.google.com/o/oauth2/auth?state=%2Fprofile

&amp;redirect_uri=https%3A%2F%2Flocalhost%2FHelloAnalytics%2FOAuth2Response.html

&amp;response_type=token

&amp;client_id=455xxxxxx.apps.googleusercontent.com

&amp;approval_prompt=auto

&amp;scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile

+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fanalytics.readonly'>

Login</a>

 

The response is parsed to get the access_token. Which is added as a param for the JSON request.

 

<!DOCTYPE>

<html>

<head>

<title>OAuth2 Handle Response</title>

</head>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" ></script>

<script type="text/javascript" language="javascript">

var tokenValue;

var gurl = "https://www.googleapis.com/analytics/v3/data/ga?callback=?";

function showReportData(data) {

if (data == null)

alert("data is null");

else {

alert("data is not null");

var JSONText = JSON.stringify(data);

document.getElementById('output').innerHTML = JSONText;

}

};

function parseResponse() {

var params = {}, queryString = location.hash.substring(1), regex = /([^&=]+)=([^&]*)/g, m;

while (m = regex.exec(queryString)) {

if (m[1] == 'access_token'){

tokenValue = m[2];

}

}

var parms = {

'access_token': tokenValue,

'ids': "ga:xxxxx28",

'start-date': "2012-03-20",

'end-date': "2012-03-30",

'metrics': "ga:visits",

'dimensions': "ga:source,ga:keyword",

'max-results': 30

}

$.getJSON(gurl, parms, showReportData);

};

</script>

<body onload="javascript:parseResponse();">

<div id="output"></div>

</body>

</html>

 

However I am getting an error:  {"error":{"errors":[{"message":"Forbidden"}],"code":403,"message":"Forbidden"}}

I also tried this in the OAuth 2.0 playground. The request was a follows


https://www.googleapis.com/analytics/v3/data/ga?

ids=ga:xxxx28

&start-date=2012-03-20

&end-date=2012-03-30

&metrics=ga:visits

&access_token=ya29.AHES6ZT-_lEKzrB6YJzYbMPZ2i0u0yIjkQI9FskTOy1p7K4

 

I get the same result.

 

But I am not sure what settings to use for the playground.

 

Is there anything else I can try next to debug this or get it working?

Thanks,

Sinead

 

 

SS

unread,
Jul 5, 2012, 11:07:11 AM7/5/12
to google-analytics...@googlegroups.com
Anyone for anymore? I've been thrawling through blogs, forums, articles - NOTHING WORKS!
 
Do I need to get request the code first - then request an access token ? Should I skip the code request - just go striaight for the access-token.
 
So many examples - so little time

Nick

unread,
Jul 9, 2012, 1:08:25 PM7/9/12
to google-analytics...@googlegroups.com
Hi,


You might consider using the query explorer to see if you can issue requests to the API: http://ga-dev-tools.appspot.com/explorer/

-Nick

SS

unread,
Jul 10, 2012, 1:20:27 PM7/10/12
to google-analytics...@googlegroups.com
Hi Nick,
thank you for your reply. The query explorer works well. It shows me that I had the wrong value for ids: and report data is returned.
 
I decided to go the route of requesting the code first. 
 
So I am capturing the code on my redirect page, and I am putting together a POST request to obtain the access_token and refresh_token. Looking at the request and response on Fiddler - it pretty much matches the request/response format in the OAuthPlayground. However instead of being able to access the JSON object returned in my callback function - a popup appears which prompts me to save the token. Is there anything here in the JS that stands out as incorrect? I think there might be a problem around the form POST.
 
 
function fetch_Token_And_RefreshToken() {
  var tokenReqParams = {
    'code': code,     //returned in response
    'client_secret': "xxxxxxxxxtrWq3xvjpUjd",
    'scope' : "",
    'grant_type': 'authorization_code'}
 
  postForToken(oauth_token_uri, tokenReqParams);
 
}
 
function postForToken(to, p) {
  var myForm = document.createElement("form");
  myForm.method = "post";
  myForm.action = to;
  for (var k in p) {
    var myInput = document.createElement("input");
    myInput.setAttribute("name", k);
    myInput.setAttribute("value", p[k]);
    myForm.appendChild(myInput);
  }
  document.body.appendChild(myForm);
 
  myForm.submit(function(event) {
    event.preventDefault();
    $.post(myForm.attr('action'), myForm.serialize(), function(json) { alert(json); }, 'json');return false;
  });
 
  document.body.removeChild(myForm);
}
 
Also just an observation - I noticed on one of the access_tokens responses, that I only received the access_token, token_type and expires in - the refresh_token was not included. Adding scope = "" to the request parameters seem to rectify.
 
Also sometimes I receive an id_token in place of refresh_token. Does this means that the access token has not expired ?
 
Thanks
Sinead
 
 

chris@shufflepoint

unread,
Jul 11, 2012, 10:25:08 AM7/11/12
to google-analytics...@googlegroups.com
The most common cause I have found for not receiving a refresh_token has been the presence of multiple grants.

Chris Harrington
ShufflePoint

Nick

unread,
Jul 13, 2012, 1:40:43 AM7/13/12
to google-analytics...@googlegroups.com
Hi,


scope is required and should be set.

Also you need to make sure Oauth is configured for a web application, and you have the proper javascript origins parameter set.

Finally there is a really nice API that we provide that handles all the auth for you: http://code.google.com/p/google-api-javascript-client/wiki/Authentication

You might consider looking into that.
-Nick

SS

unread,
Jul 19, 2012, 9:51:36 AM7/19/12
to google-analytics...@googlegroups.com
Hi,
thanks for your post.
 
Nick - the article you mention https://developers.google.com/accounts/docs/OAuth2UserAgent   is really quite a good guide and this was the route I first set out on. My downfall was having the incorrect Profile ID. Which then led me on to a whole other journey trying to request the code first. Looking at the Google Analytics account it just wasn't that clear which value was the Porfile ID. I'm not the person who set up the account - so maybe this is where this confusion crept in.
 
So for anyone wondering where the Profile ID is - go to your google analytics account and you will see the Profile ID at the end of the URL eg
 
 
The Profile ID is the number at the end eg. p555566
Don't confuse it with the accountId (which is what I was doing!) or the internalWebPropertyId.
 
I've since gone back to the requesting the token first using Javascript and the API is returning the report information <*big sigh*>
 
So just to clarify:  
In order for other end users to use my Web Site displaying the report info (ie no need to supply account credentials), is it correct to say the Google Analytic account must be left 'Signed In' - otherwise users will be prompted for the account credentials? And when account status is 'Signed In' they are shown the 'Allow' button. And status 'Signed In' will remain until someone clicks 'Sign Out' ?
 
Chris, for the requesting the code first route - I only ever specified a single grant type at any one time. I'd still be curious if it is possible to request the code via Javascript - I was following a PHP /CURL example :)
 
Sinead
 
 
Reply all
Reply to author
Forward
0 new messages