Google Analytics 3.0身份validation流程

编辑:最初这个问题询问我如何仅使用我的API密钥对Google AnalyticsAPI进行身份validation。 正如vlatko指出的那样 ,这是不可能的。 现在我只专注于让OAuth2工作。 当我有机会时,我会尝试vlatko的建议,并会更新问题。 在此期间,您可以随意为您认为我缺少的任何事情贡献答案。


原始问题:

我正在尝试向Google AnalyticsAPI提出请求。 我正在浏览Hello Analytics教程,尝试复制这些步骤。 无论我尝试什么,我似乎都无法成功地进行身份validation。

该教程说明如下:

打开您创建的名为HelloAnalyticsApi.java的文件,并添加以下方法:

 private static Analytics initializeAnalytics() throws Exception { // Authorization. Credential credential = OAuth2Native.authorize( HTTP_TRANSPORT, JSON_FACTORY, new LocalServerReceiver(), Arrays.asList(AnalyticsScopes.ANALYTICS_READONLY)); // Set up and return Google Analytics API client. return Analytics.builder(HTTP_TRANSPORT, JSON_FACTORY) .setApplicationName("Google-Analytics-Hello-Analytics-API-Sample") .setHttpRequestInitializer(credential) .build(); } 

当用户遇到此脚本时,应用程序将尝试打开默认浏览器并将用户导航到google.com上托管的URL。 此时,将提示用户登录并授予应用程序访问其数据的权限。 一旦授予,应用程序将尝试从浏览器窗口中读取代码,然后关闭窗口。

不同之处在于我正在尝试使用servlet应用程序执行此操作,并且我希望使用API​​密钥(而不是OAuth 2.0客户端ID)进行简单的API访问。 我知道建议使用OAuth 2.0,但我只需要访问我拥有的数据并希望简化技术要求。 我在这个页面上做出了这个决定,其中说:

API密钥是您使用控制台生成的唯一密钥。 当您的应用程序需要调用在此项目中启用的API时,应用程序会将此密钥作为key={API_key}参数传递给所有API请求。 使用此密钥不需要任何用户操作或同意,不授予对任何帐户信息的访问权限,也不用于授权。

如果您只调用不需要用户数据的API(例如Google Custom Search API),那么API密钥可能更容易实现。 但是,如果您的应用程序已使用OAuth 2.0访问令牌,则无需生成API密钥。 实际上,如果OAuth 2.0访问令牌已经与相应的项目相关联,则Google会忽略已传递的API密钥。

我只是使用API​​密钥找不到许多auth流程的代码示例 – 我发现的大部分内容都使用客户端ID和下载的.p12文件显示,例如GoogleCredential javadoc。 我能找到的一个示例应用程序是Google的Books Sample应用程序。 无论如何,这是我尝试的(模仿教程中的第一个请求,它从管理API获取帐户列表):

 Analytics analytics = new Analytics.Builder(httpTransport, jsonFactory, null) .setApplicationName("Dev API Access") .build(); Management.Accounts.List list = analytics.management().accounts().list().setKey(apiKey); Accounts accounts = list.execute(); 

“Dev API Access”是我的API控制台仪表板中的“名称”字段。 API密钥是仅限于我的IP地址的服务器密钥。 这会因以下响应而失败:

 401 Unauthorized { "code": 401, "errors": [ { "domain": "global", "location": "Authorization", "locationType": "header", "message": "Login Required", "reason": "required" } ], "message": "Login Required" } 

我也试过这个:

 Analytics analytics = new Analytics.Builder(httpTransport, jsonFactory, null) .setApplicationName("Dev API Access") .setGoogleClientRequestInitializer(new AnalyticsRequestInitializer(apiKey)) .build(); Management.Accounts.List list = analytics.management().accounts().list(); Accounts accounts = list.execute(); 

哪个显示相同的错误。 我在这做错了什么? 分析调用需要OAuth2吗? 如果是这样,为什么只使用API​​示例应用程序中的API密钥?


继续,我继续尝试OAuth2 – 我创建了一个客户端ID并下载了.p12私钥文件。 但我也无法做到这一点。 这是我尝试过的:

 Credential credential = new GoogleCredential.Builder() .setTransport(httpTransport) .setJsonFactory(jsonFactory) .setServiceAccountId(serviceAccountId) .setServiceAccountScopes(AnalyticsScopes.ANALYTICS_READONLY) .setServiceAccountPrivateKeyFromP12File(new File(p12FilePath)) .setServiceAccountUser(serviceAccountUser) .build(); Analytics analytics = new Analytics.Builder(httpTransport, jsonFactory, credential) .setApplicationName("Dev API Access") .build(); Management.Accounts.List list = analytics.management().accounts().list(); Accounts accounts = list.execute(); 

其中serviceAccountId是拥有项目的Google帐户的电子邮件地址, serviceAccountUser是生成的客户端ID上列出的电子邮件地址。 这失败了以下内容:

 400 Bad Request { "error": "invalid_grant" } 

“无效授权”是什么意思,我如何成功进行身份validation(理想情况下没有OAuth2)?

回答第一个问题:通常,OAuth2.0用于授权访问用户的私有数据,因此需要获得用户同意并获取访问令牌。 但是,对于Google Books API,如果您正在访问公共数据,则无需最终用户同意,因此API密钥就足够了。 如果您尝试使用Books API访问非公开数据,则仍需要OAuth2令牌。

对于您的案例来说,好消息是,即使使用OAuth2,您也可以绕过用户参与并使用服务帐户简化流程 – 假设您的应用程序可以访问API。 有一种方法可以为Analytics API进行设置,如下所述(请查看“服务帐户”部分中的步骤)。 我认为您与Credential构建器处于正确的轨道上,但我认为您不需要在那里设置服务帐户用户,因为您没有进行任何用户模拟。

vlatko的回答让我走上正轨。 问题原来是我将所有者电子邮件地址与服务帐户电子邮件地址混淆。 例如,我正在做以下事情:

 Credential credential = new GoogleCredential.Builder() .setTransport(httpTransport) .setJsonFactory(jsonFactory) .setServiceAccountId("owneremail@gmail.com") //wrong .setServiceAccountScopes(AnalyticsScopes.ANALYTICS_READONLY) .setServiceAccountPrivateKeyFromP12File(new File(p12FilePath)) .setServiceAccountUser("xxx@developer.gserviceaccount.com") //unnecessary .build(); 

当我需要这样做时:

 Credential credential = new GoogleCredential.Builder() .setTransport(httpTransport) .setJsonFactory(jsonFactory) .setServiceAccountId("xxx@developer.gserviceaccount.com") .setServiceAccountScopes(AnalyticsScopes.ANALYTICS_READONLY) .setServiceAccountPrivateKeyFromP12File(new File(p12FilePath)) .build(); 

此外,我在我的Analytics应用程序中添加了owneremail@gmail.com作为用户 – 这同样需要是服务帐户电子邮件。