Google推送通知 - 未经授权的WebHook回调频道

时间:2014-05-29 08:15:11

标签: java google-api google-drive-api google-api-java-client

我遇到谷歌推送通知(驱动器)的问题。我使用的服务帐户非常适用于所有其他驱动器操作,除了驱动器更改监视。

以下是现在因“未授权的WebHook回调通道”异常而失败的应用程序代码。我还转储了调用drive.changes.watch.execute时生成的请求和响应。

目标通知地址列在API& auth推送控制面板(我甚至将它列在Javascript起源和引用中),现在我遇到了这个401 Unauthorized错误。

有人知道我在哪里弄错了吗?谢谢你的帮助。

PrivateKey serviceAccountPrivateKey = SecurityUtils.loadPrivateKeyFromKeyStore(SecurityUtils.getPkcs12KeyStore(), p12File, "notasecret", "privatekey", "notasecret");
JsonFactory jsonFactory = new JacksonFactory();
HttpTransport t = GoogleNetHttpTransport.newTrustedTransport();
GoogleCredential gc = new GoogleCredential.Builder()
                .setTransport(t)
                .setJsonFactory(jsonFactory)
                .setServiceAccountScopes(Collections.singleton(DriveScopes.DRIVE))
                .setServiceAccountPrivateKey(serviceAccountPrivateKey)
                .setServiceAccountId(Config.SERVICE_ACCOUNT_ID)
                .setServiceAccountUser(Config.SERVICE_ACCOUNT_USER)
                .build();

drive = new Drive.Builder(t, jsonFactory, null).setHttpRequestInitializer(gc).setApplicationName(cfg.getStringParam(Config.GAE_APPLICATION_NAME)).build();

// THIS WORKS
Changes.List request = drive.changes().list();
ChangeList changes = request.execute();

// THIS DOES NOT WORK
Channel channel = new Channel();
channel.setId(UUID.randomUUID().toString());
channel.setType("web_hook");
channel.setAddress(Config.PUSH_NOTIFICATION_ADDRESS);
Channel c = drive.changes().watch(channel).execute();


-------------- REQUEST  --------------
POST https://www.googleapis.com/drive/v2/changes/watch
Accept-Encoding: gzip
Authorization: Bearer XXX
User-Agent: XXX Google-HTTP-Java-Client/1.17.0-rc (gzip)
Content-Type: application/json; charset=UTF-8
Content-Length: 118

CONFIG: curl -v --compressed -X POST -H 'Accept-Encoding: gzip' -H 'Authorization: Bearer XXX' -H 'User-Agent: XXX Google-HTTP-Java-Client/1.17.0-rc (gzip)' -H 'Content-Type: application/json; charset=UTF-8' -d '@-' -- 'https://www.googleapis.com/drive/v2/changes/watch' << $$$
CONFIG: {"address":"XXX","id":"8078114c-fba0-44e7-a34c-cb391ea40061","type":"web_hook"}

-------------- RESPONSE --------------
401 OK
www-authenticate: Bearer realm="https://accounts.google.com/AuthSubRequest", error=invalid_token

-------------- REQUEST  --------------
POST https://accounts.google.com/o/oauth2/token

-------------- RESPONSE --------------
200 OK
{
  "access_token" : XXX,
  "token_type" : "Bearer",
  "expires_in" : 3600
}

-------------- REQUEST  --------------
POST https://www.googleapis.com/drive/v2/changes/watch

-------------- RESPONSE --------------
401 OK
www-authenticate: Bearer realm="https://accounts.google.com/AuthSubRequest", error=invalid_token

...
...
...

-------------- RESPONSE --------------
200 OK
content-type: application/json; charset=utf-8
cache-control: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
expires: Fri, 01 Jan 1990 00:00:00 GMT
date: Wed, 28 May 2014 20:51:19 GMT
content-disposition: attachment; filename="json.txt"; filename*=UTF-8''json.txt
content-encoding: gzip
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
server: GSE
alternate-protocol: 443:quic
transfer-encoding: chunked

{
  "access_token" : XXX,
  "token_type" : "Bearer",
  "expires_in" : 3600
}

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "push.webhookUrlUnauthorized",
    "message": "Unauthorized WebHook callback channel: XXX"
   }
  ],
  "code": 401,
  "message": "Unauthorized WebHook callback channel: XXX"
 }
}

5 个答案:

答案 0 :(得分:17)

您必须将您的域添加到开发人员控制台。

如何:

  1. 登录Google Developers Console
  2. 选择您的项目
  3. &#39; APIS&amp; AUTH&#39;选择&#39;推送&#39;
  4. 点击“添加域名”
  5. 输入所需的域(仅需要域,而不是整个通知URL)
  6. 点击“添加域名”&#39;按钮
  7. 之后它应该有效,除非你正在做的事情出现其他问题:p

答案 1 :(得分:5)

对我而言,正如我在上面发表评论,

域名验证未在Google开发者控制台中保存(刷新页面并且已消失)。问题最终导致我以两个谷歌帐户,我的Gmail帐户和我的公司帐户登录。添加域验证似乎对帐户感到困惑,而不是保存域设置。

如果您使用多个Google帐户,请尝试使用其他浏览器或隐身会话登录。

答案 2 :(得分:0)

对我来说,我希望回调Webhook URL为https://test-apis.domain.io。因此,为了进行域验证,我添加了test-apis.domain.io,然后尝试修改TXT记录,但该记录从未起作用(验证)。

最后,使用相同的方法仅验证了domain.io。完成此操作后,我可以在凭据“域验证”屏幕中添加域test-apis.domain.io。希望这对其他人也有帮助。

答案 3 :(得分:0)

我确认我的域,检查了我的SSL,但问题没有解决。

最后,我找到了解决方案:在Google Developers Console中使用 Service Acconut Key (不是API密钥,也不是OAuth客户端ID)。

答案 4 :(得分:0)

这都是由于console.developers.google.com上的“设置”所致。您需要将后端域添加到(“ OAuth同意屏幕”选项卡上)的“授权域”和“域验证”选项卡上的“允许的域”中。

所以它现在对您有用的原因是,您可能已经验证并添加了顶级域,而您的本地环境当时有单独的域(不是经过验证的顶级子域),特别是在您已经在Internet上公开了本地服务器。