简体   繁体   English

如何验证Google Contacts API的Java应用程序?

[英]How to authenticate a java application for the Google Contacts API?

I've had a java application running for a few years that synced some contacts from some database into the gmail account of a customer. 我有一个运行了几年的Java应用程序,它已将某些联系人从某些数据库同步到客户的gmail帐户中。

This stopped working a few days ago, presumably because Google stopped supporting the simple username/password authentication. 几天前,此操作停止了,可能是因为Google 停止了支持简单的用户名/密码身份验证。

First question: Am I correct in assuming that the only supported authentication now is OAuth2? 第一个问题:假设现在唯一支持的身份验证是OAuth2,是否正确?

Assuming that is the case, I don't understand what kind of authorization scheme/flow I should use. 假设是这种情况,我不知道应该使用哪种授权方案/流程。 I can't show a dialog - this is a service type kind of application, and it should only access one specific customer account that I control. 我无法显示对话框-这是一种服务类型的应用程序,它只能访问我控制的一个特定客户帐户。 I think I should use a Service Account , but the documentation says this: 我认为我应该使用“ 服务帐户” ,但是文档中指出:

Typically, an application uses a service account when the application uses Google APIs to work with its own data rather than a user's data. 通常,当应用程序使用Google API来处理其自身的数据而不是用户的数据时,该应用程序将使用服务帐户。

But I want to use user data - the Contacts, specifically. 但我想使用用户数据-具体来说就是“联系人”。

For that scenario the documentation has this to say: 对于这种情况,文档说明如下:

If you have a Google Apps domain—if you use Google Apps for Work, for example—an administrator of the Google Apps domain can authorize an application to access user data on behalf of users in the Google Apps domain. 如果您拥有Google Apps域(例如,如果您使用Google Apps for Work),则Google Apps域的管理员可以授权应用程序代表Google Apps域中的用户访问用户数据。 For example, an application that uses the Google Calendar API to add events to the calendars of all users in a Google Apps domain would use a service account to access the Google Calendar API on behalf of users. 例如,使用Google Calendar API将事件添加到Google Apps域中所有用户的日历的应用程序将使用服务帐户代表用户访问Google Calendar API。 Authorizing a service account to access data on behalf of users in a domain is sometimes referred to as "delegating domain-wide authority" to a service account. 授权服务帐户代表域中的用户访问数据有时称为“将域范围的权限委派给服务帐户”。

But, I don't have a Google Apps domain. 但是,我没有Google Apps域。

So... now what? 那么现在怎么办?

First question: Am I correct in assuming that the only supported authentication now is OAuth2? 第一个问题:假设现在唯一支持的身份验证是OAuth2,是否正确?

Yes

So... now what? 那么现在怎么办?

The closest analogy to a username-password is a refresh token (which is simply a string). 与用户名密码最接近的类比是刷新令牌(它只是一个字符串)。 IE:- IE:-

  • If your app has a refresh token, it can, at any time, access the resources granted to it 如果您的应用程序具有刷新令牌,则它可以随时访问授予它的资源
  • Because of the power of a refresh token, it needs to be securely stored, just like a password 由于刷新令牌的功能强大,因此需要像密码一样安全地存储它

The steps required to get a refresh token are described here How do I authorise an app (web or installed) without user intervention? 此处介绍了获取刷新令牌所需的步骤。 如何在没有用户干预的情况下授权应用程序(网络或已安装)? (canonical ?) (规范?)

That answer also contains a link which points to the Google docs for how to use a refresh token to obtain an access token. 该答案还包含指向Google文档的链接,该链接说明了如何使用刷新令牌来获取访问令牌。

And here some code (based on pinoyyid's suggestion): 这是一些代码(基于pinoyyid的建议):

String CLIENT_ID = "see instructions in accepted answer";
String CLIENT_SECRET = "see instructions in accepted answer";
String REFRESH_TOKEN = "see instructions in accepted answer";

Builder builder = new GoogleCredential.Builder();
builder.setTransport(GoogleNetHttpTransport.newTrustedTransport());
builder.setJsonFactory(JacksonFactory.getDefaultInstance());
builder.setClientSecrets(CLIENT_ID, CLIENT_SECRET);

Credential credential = builder.build();
credential.setRefreshToken(REFRESH_TOKEN);
credential.refreshToken(); // gets the access token, using the refresh token

ContactsService contactsService.setOAuth2Credentials(credential);

Query query = new Query(new URL("https://www.google.com/m8/feeds/contacts/default/full"));
query.setMaxResults(10_000);

ContactFeed allContactsFeed = contactsService.getFeed(query, ContactFeed.class);

LOGGER.log(Level.INFO, allContactsFeed.getTitle().getPlainText());

for(ContactEntry contact : allContactsFeed.getEntries())
{
  ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM