Jus*_*ips 18 google-calendar-api oauth-2.0 google-api-java-client google-oauth
首先,让我解释一下我要做的事情,因为这是一个两部分问题.
我建立在内部通过的OAuth2一个谷歌帐户验证一个JAX-RS的服务,所以它可以访问和操作谷歌日历.这项服务将通过一个网站(的Joomla),这将允许登录到网站的用户注册与日历事件他们的电子邮件地址,以便他们可以得到电子邮件通知当事件附近被调用.这些用户不了解底层Google帐户.
所以我的第一个问题是使用服务帐户身份验证是正确的吗?查看Google文档,它是唯一适合非人类身份验证的用例(因此服务器到服务器身份验证).
第二个问题是,我已经写了一些代码来做到这一点,但我拿回401 /未经授权的响应返回以下错误回来时,我调用execute方法日历饲料.此代码已从Google示例中取消.
我正在使用Google Calendar API的v3-rev3-1.5.0-beta.我已在帐户中启用了Calendar API,并创建并下载了私钥,该私钥在下面的代码中使用.
我在本地调用Eclipse中的代码,而不是从Web服务器调用.
所以我做的第一个调用是取回一个凭证对象(Id用X混淆):
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
.
.
.
GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("284XXXXXXXX@developer.gserviceaccount.com")
.setServiceAccountScopes(CalendarScopes.CALENDAR)
.setServiceAccountPrivateKeyFromP12File(new File("D:/3cd8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXd635e-privatekey.p12"))
.build();
Run Code Online (Sandbox Code Playgroud)
下一步是调用Calendar API,就像这样(之间没有其他代码调用):
Calendar calendar = Calendar.builder(HTTP_TRANSPORT, JSON_FACTORY)
.setApplicationName("TestApp-Calendar/1.0").setHttpRequestInitializer(credential)
.build();
CalendarList feed = calendar.calendarList().list().execute();
Run Code Online (Sandbox Code Playgroud)
对list().execute()的调用导致以下错误:
com.google.api.client.googleapis.json.GoogleJsonResponseException:401 Unauthorized {"code":401,"errors":[{"domain":"global","location":"Authorization","locationType":"标题","消息":"需要登录","原因":"必需"}},"消息":"需要登录"} com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException. java:159)com.google.api.client.googleapis.json.GoogleJsonResponseException.execute(GoogleJsonResponseException.java:187)com.google.api.client.googleapis.services.GoogleClient.executeUnparsed(GoogleClient.java:115) at com.google.api.client.http.json.JsonHttpRequest.executeUnparsed(JsonHttpRequest.java:112)at the com.google.api.services.calendar.Calendar $ CalendarList $ List.execute(Calendar.java:510)at uk .org.reigatepriorybowmen.Service.registerEmailForAllCalendarEvents(Service.java:55)at uk.org.reigatepriorybowmen.Service.main(Service.java:74)
服务帐户设置如下:

那么,我做错了什么?!我花了几个小时在谷歌上寻找解决方案,所以这是我最后的希望.
非常感谢您的帮助.
贾斯汀
至于401,谷歌的API似乎有些奇怪.我发现我第一次运行我的应用程序,然后在看似随机的时间间隔小时分开,我总是得到401.在第二轮或第三轮它实际上登录.
该行为即使是在谷歌的任务API的示例代码占了这里.
请注意此代码:
void onRequestCompleted() {
received401 = false;
}
void handleGoogleException(IOException e) {
if (e instanceof GoogleJsonResponseException) {
GoogleJsonResponseException exception = (GoogleJsonResponseException) e;
if (exception.getStatusCode() == 401 && !received401) {
received401 = true;
accountManager.invalidateAuthToken(credential.getAccessToken());
credential.setAccessToken(null);
SharedPreferences.Editor editor2 = settings.edit();
editor2.remove(PREF_AUTH_TOKEN);
editor2.commit();
gotAccount();
return;
}
}
Log.e(TAG, e.getMessage(), e);
Run Code Online (Sandbox Code Playgroud)
}
在谷歌自己的代码示例中,他们首次提供了401.可能需要在代码中处理一些特殊的安全问题.
我认为您需要指定您试图模拟的用户。
您现在使用 ServiceAccount 的方式仅适用于访问与您的应用程序或服务帐户本身相关的数据。由于您希望访问 Google 日历数据,因此您必须是具有访问任何域用户数据权限的 Google Apps 域管理员 - 如果我的说法不正确,请告诉我。Google 日历数据属于用户,因此您需要指定要尝试模拟的用户。
要使用 Java 执行此操作,似乎您需要使用GoogleCredential.Builder#setServiceAccountUser(String)
请尝试:
GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("284XXXXXXXX@developer.gserviceaccount.com")
.setServiceAccountScopes(CalendarScopes.CALENDAR)
.setServiceAccountPrivateKeyFromP12File(new File("/path/to/privatekey.p12"))
.setServiceAccountUser("user@domain.com")
.build();
Run Code Online (Sandbox Code Playgroud)
此外,在 API 项目中(从 API 控制台)创建服务帐户密钥后,您必须将该项目添加到 cPanel 中授权的第三方应用程序列表中。有关此内容的更多信息可以在此处找到。您需要使用的“客户端 ID”是绑定到服务帐户密钥的“客户端 ID”,如下所示<APP_ID>-<OTHER_KEY>.apps.googleusercontent.com
| 归档时间: |
|
| 查看次数: |
36218 次 |
| 最近记录: |