6

在过去的几天里,我看到一个长期运行的实时应用程序出现了一些越来越严重的问题。我已经完成了以下步骤,底部的代码片段包含来自应用程序的其他调试信息。

当页面首次打开时,它成功请求 OAuth 令牌并加载实时文档 [A]。50 分钟后(令牌过期前 10 分钟),它成功重新请求新的 OAuth 令牌 [B]。在第一个令牌过期后,当前打开的连接会收到 401 未授权错误并需要新的 oauth 令牌 [C]。这本身似乎是一个问题,因为它应该更新自己以使用来自 [B] 的新的有效令牌。

但是,该应用程序仍应能够应对此类错误发生 - 因此通过关闭并重新打开文档 [D] 并获取另一个新的 OAuth 令牌来处理它。不幸的是,此时实时 API 处于无限循环中,获取 access_token [E] 的错误。

所有 OAuth 令牌都是使用具有相同范围的 gapi.auth.authorize 请求的,并且不调用 setToken。我之前尝试过使用 setToken,但遇到了完全相同的问题。

实际问题 为实时 API 刷新 OAuth 令牌的正确方法是什么?关闭和重新打开文档时,如何防止驱动器 API 内部重复出现故障?

[A]
_aa: "1"
access_token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXz9AYBkyympssqI"
client_id: "XXXXXXXXXXXXXXXX.apps.googleusercontent.com"
cookie_policy: undefined
expires_at: "1373610287"
expires_in: "3600"
g_user_cookie_policy: undefined
issued_at: "1373606687"
response_type: "token"
scope: Array[2]
state: ""
token_type: "Bearer"

[B]
_aa: "1"
access_token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXV2kzG4EMUppi"
client_id: "XXXXXXXXXXXXXX.apps.googleusercontent.com"
cookie_policy: undefined
expires_at: "1373613288"
expires_in: "3600"
g_user_cookie_policy: undefined
issued_at: "1373609688"
response_type: "token"
scope: Array[2]
state: ""
token_type: "Bearer"

[C]
GET https://drive.google.com/otservice/bind?id=1B-XXXXXXXXXXXXXXXXXXXXX_nRizfqmT…&RID=rpc&SID=XXXXXXXXXXXXXXXXX&CI=0&AID=221&TYPE=xmlhttp&zx=ns6e5dr7rf4&t=1 401 (Unauthorized)

Drive Realtime API Error: token_refresh_required: The OAuth token must be refreshed. 

[D]
[Close Realtime Document]
[Open Realtime Document]

_aa: "1"
access_token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMHzJXm2dF-"
client_id: "XXXXXXXXXXXXXX.apps.googleusercontent.com"
cookie_policy: undefined
expires_at: "1373613918"
expires_in: "3600"
g_user_cookie_policy: undefined
issued_at: "1373610318"
response_type: "token"
scope: Array[2]
state: ""
token_type: "Bearer"

[E]
[x100] Uncaught TypeError: Cannot read property 'o' of null 

谢谢!

4

1 回答 1

9

我看了你的问题,我认为你对两个主要问题是正确的。

  1. API 不会自动获取刷新的令牌。
  2. 关闭和重新打开文档会导致周期性的“无法读取属性 'o' of null”错误。

关于问题 1,我们会在每次保存更改时以及在服务器到客户端的连接不健康时(例如,在 401 错误之后)每秒获取一个刷新的令牌。这显然没有涵盖的是您提前刷新令牌并且文档没有任何更改的情况。在这种情况下,即使您已经更新了令牌,您也会看到 401。我正在解决这个问题,在连接正常时每 30 秒获取一次刷新的令牌。最终,我们希望这是事件驱动的,以便立即获取令牌,但这有点涉及更多,因为它需要更改 gapi.auth。

关于问题 2,根据我的测试,周期性错误似乎是虚假的(在内部,即使文档已关闭,我们仍在尝试刷新旧文档的令牌,这就是您得到“无法读取属性”的原因错误)。我也在努力解决这个问题,但是您仍然应该能够重新加载文档(尽管您会看到旧文档的大量垃圾错误)。请让我知道如果不是这种情况并且您真的无法重新加载文档。

我应该注意,当您收到令牌刷新错误时,您不需要重新加载文档。这由传递给错误处理程序的 gapi.drive.realtime.Error 对象的 isFatal 属性为 false 的事实表明,这表明错误是可恢复的。token_refresh_required 错误的建议响应是刷新令牌 - 网络服务应该自动赶上。如果这不起作用,请随时让我知道,因为这是一个错误。

-- Brian(实时 API 开发人员)

于 2013-07-12T21:42:41.080 回答