0
votes

Here's what I'm trying to do: I'm trying to generate an access token on the server side that will serve to authenticate a user as in this example:

https://ga-dev-tools.appspot.com/embed-api/server-side-authorization/

I've written this code in VB.net after several tries:

Public GA_Token As String

Protected Sub Page_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    Dim filename As String = {{path to p12 file}}
    Dim serviceAccountEmail As String = {{service account generated email from IAM & Admin from console.developers.google.com of the form user@project name.iam.gserviceaccount.com}}
    Dim certificate = New X509Certificate2(filename, "password", X509KeyStorageFlags.Exportable Or X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet)
    Dim Scopes As IEnumerable(Of String) = {AnalyticsService.Scope.AnalyticsReadonly}
    Dim credential As New ServiceAccountCredential(New ServiceAccountCredential.Initializer(serviceAccountEmail) With {.Scopes = Scopes}.FromCertificate(certificate))
    GA_Token = credential.GetAccessTokenForRequestAsync(Request.Url.ToString, CancellationToken.None).Result

End Sub

GA_Token is then written to the Analytics page I created.

The problem is that, when I go to view the reports, I get a 403 error from Chrome.

Objectbody: "{"error":{"errors":[{"domain":"global","reason":"insufficientPermissions","message":"User does not have any Google Analytics account."}],"code":403,"message":"User does not have any Google Analytics account."}}"headers: Objectcache-control: "private, max-age=0"content-encoding: "gzip"content-length: "146"content-type: "application/json; charset=UTF-8"date: "Fri, 18 Nov 2016 18:25:08 GMT"expires: "Fri, 18 Nov 2016 18:25:08 GMT"server: "GSE"vary: "Origin, X-Origin"www-authenticate: "Bearer realm="https://accounts.google.com/", error=insufficient_scope, scope="https://www.googleapis.com/auth/analytics.edit""proto: Object__defineGetter__: defineGetter()defineSetter: defineSetter()lookupGetter: lookupGetter()lookupSetter: lookupSetter()constructor: Object()hasOwnProperty: hasOwnProperty()isPrototypeOf: isPrototypeOf()propertyIsEnumerable: propertyIsEnumerable()toLocaleString: toLocaleString()toString: toString()valueOf: valueOf()get proto: proto()set proto: proto()result: Objecterror: Objectcode: 403errors: Array[1]0: Objectlength: 1__proto__: Array[0]message: "User does not have any Google Analytics account."proto: Object__proto__: Objectstatus: 403statusText: null__proto__: Object_.nH @ cb=gapi.loaded_0:606_.du.Vh @ cb=gapi.loaded_0:742(anonymous function) @ view-selector2.js:109h.o0 @ cb=gapi.loaded_0:75xs @ cb=gapi.loaded_0:78Wq @ cb=gapi.loaded_0:78_.C.uea @ cb=gapi.loaded_0:77Ap @ cb=gapi.loaded_0:71 cb=gapi.loaded_0:67 Uncaught Object {result: Object, body: "{"error":{"errors":[{"domain":"global","reason":"i…er does not have any Google Analytics account."}}", headers: Object, status: 403, statusText: null}(anonymous function) @ cb=gapi.loaded_0:67

Now, I can use the OAuth2 protocol to generate the token and have it display if the user logs in to his/her account, but I'm trying to bypass that. The problem I'm running into is that I don't see where I'm supposed to set the permissions for the account. I went into IAM and Admin and enabled Domain-wide Delegation on two different service accounts to test with. I set them with every permission imaginable (which worked out to Owner + 18 other permissions). Where else do I need to set permissions, or am I overlooking something?

3
Wow 16 upvotes, 1 downvote... thats the lowest I've ever seen!Jeremy Thompson
I'm sorry, but I don't see any upvotes or downvotes. Was this for me?SEFL

3 Answers

1
votes

First, set the User email like this here, not sure how to do that in VB.

You say:

I can use the OAuth2 protocol to generate the token and have it display if the user logs in to his/her account, but I'm trying to bypass that.

But I see that you're also trying to use a Google Service Account, which I think only works if you are a paying G Suite user.

I've spent a lot of time to figure this out for my Gmail client and by accident found the solution: The permissions should be visible per user under Connected Apps. But this does mean however that your user has to manually grant access once, after that you can just get a token using the Google Service Account.

0
votes

I tried and it works for me.

I had previously setup a Project called "YYYassistant" and I created an account:

enter image description here

Then I created a simple WinForm app and could not reproduce the issue, this works:

Imports Google.Apis.Auth.OAuth2
Imports System.Security.Cryptography.X509Certificates

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim scopes As String() = New String() {AnalyticsService.Scope.Analytics}
        ' view and manage your Google Analytics data
        Dim keyFilePath = "C:\Temp\YYYassistant-1234db98765.p12"
        ' Downloaded from https://console.developers.google.com
        Dim serviceAccountEmail = "[email protected]"
        ' found https://console.developers.google.com
        'loading the Key file
        Dim certificate = New X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable)
        Dim credential = New ServiceAccountCredential(New ServiceAccountCredential.Initializer(serviceAccountEmail) With {.Scopes = scopes}.FromCertificate(certificate))
    End Sub
End Class

"code":403,"message":"User does not have any Google Analytics account."

Its a problem with your account, make a new one.

0
votes

The issue is explained on the Json

"{"error":{"errors":[{"domain":"global","reason":"insufficientPermissions","message":"User does not have any Google Analytics account."}]

{ "User does not have any Google Analytics account." } 

Maybe change the code will not change anything, because it's an access error. In a few words, You gmail used to get the Token has no account linked. The validation process for the Auth look wells. Before change code i recommend you do the following steps.

1.- Get a valid Email and Passwords

I can believe you already got this (you already have the toke), grab this credentials and go to

https://analytics.google.com/analytics/web/ , login with these credential and And see if you have any account linked.

If you account have no access you will see enter image description here

Note: If you use the Oauth validate, the email used to get the token can be different that the one used on the project, maybe you need to use someone else's credentials. Be 100% sure of what credential are you using.

2.- If you have no account you need to ask access, so the user with the Google Analytics Account needs to give you access. In the desired account you need to go Admin -> User Management , and add the email used on the Validation Process: enter image description here When you have you token, remember store it and refresh it whenever you need, the tokens needs to be mananged

3.- If you want to get your own data, maybe you can use a P12key, as Jeremy says, this method is more easy to validate, but you need to add the p12key on every query (usually the library does it for you). But with this method you can only access to data linked to your own gmail account. If you change the method you can have the same error, that it the need to be 100% of the used account