替代每次调用 gapi.auth.authorize

Alternative to calling gapi.auth.authorize every time

我有一个单页 Web 应用程序,它使用 Google Apps 脚本执行 API 来调用 return 我需要的数据的函数。我的项目基于 quick start sample code provided by Google.

这需要使用 OAuth,我正在通过使用 the client JavaScript library provided by Google.

的函数来实现这一点

第一次要求用户验证以下功能与 immediate: false 一起使用:

gapi.auth.authorize({client_id: CLIENT_ID, scope: SCOPES, immediate: false}, handler);

后续 API 请求还必须提供身份验证令牌,因此我调用了相同的函数,但使用 immediate: true:

gapi.auth.authorize({'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': true}, handler);

每调用一次gapi.auth.authorize,页面就会增加一个新的IFRAME,貌似用来存放认证结果operation/token等

所以,是的,一切正常,但我认为必须有更好的方法来做到这一点。

是否有另一种方法可以进行后续 API 调用,在初始身份验证后,不需要使用 gapi.auth.authorize 并向 IFRAME 添加另一个 IFRAME页数?

根据Google:

Notes

After the initial user authorization, calls to gapi.auth.authorize that use immediate:true mode will obtain an auth token without user interaction.

简而言之,除非您使用 "offline" 模式,否则您无法避免使用 iframe(或较旧的弹出窗口)。这是交易:
有两种不同的方法可以请求权限,"offline" 或 "not offline"。

Offline 中,oauth2 通过给你 "refresh token" 给你一个永久的权限(好的,如果用户从 google 帐户安全页面,或者在用户更改密码的某些范围内)。

这个特殊令牌让您可以随时创建新的访问令牌,只需对 API 进行 "GET" 调用,无需任何用户干预。 在你的情况下,这是你需要的模式,没有办法绕过它,这就是它存在的原因,你必须特别注意安全地存储它等等。

非离线模式下,您只会获得临时权限("access token" 1小时后过期),您不会获得"refresh token"。但它是如何工作的呢?某处必须有一些刷新令牌或私人存储的东西。

Authentication using the Google APIs Client Library for JavaScript 利用浏览器的安全功能来做到这一点。特别是,浏览器保护每个子域的存储和 cookie,一旦您登录到浏览器,google.com 将存储或使用 cookie 来保护它发送给 google 以验证您的参数。
那么,如何读取这些值呢?打开 google.com url 是让 javascript 读取值的唯一方法。 Google 允许特殊参数,因此它可以传回访问令牌。如何打开一个页面? by "iframe" 或 "popup" 是浏览器当前支持的唯一方式。

这允许 google 页面像一个安全代理一样向 Google 询问内容。 iframe 或打开 google 页面(作为弹出窗口)的页面无法伪造自己的 URL,因此此 "proxy" 知道哪个页面正在请求数据。然后,代理可以使用 google 服务器验证此调用者具有的范围,并 return 一个新的访问令牌。黑客无法从服务器伪造它,因为它没有所需的 cookie(存储在每个用户的浏览器中的 google 子域下,这是 "online" 模式唯一起作用的地方。)

"popup" 是浏览器保护 iframe 之前的旧方法,但当弹出窗口打开并立即关闭时,它至少会导致 "flash"(在上面的 link 中搜索 "jarring" )

因此,后来 Google 提供了 "iframe" 模式,提供了更流畅的体验。使用iframe就是上面link提到的"immediate"模式

TLDR:必须使用 "offline" 或破解用户的浏览器。